关于js中局部变量的作用范围

发布于 2022-08-30 16:39:35 字数 1610 浏览 33 评论 0

如下代码1:

function f1(param){
    $.ajax({
        xxx:xxx,//参数省略
        success:function(data){
            alert(param);
        }
    });
}
f1("HelloWorld");

请问,HelloWorld可以alert出来吗?


我遇到的问题是:当ajax请求成功后,偶尔会,但偶尔undefined。(当然,程序的背景可能不一样,但基本是这个结构)
遇到undefined时,我利用闭包去解决这个问题:
如下代码2:

function f1(param){
    function getParam(){
        return param;
    }
    $.ajax({
        xxx:xxx,//参数省略
        success:function(data){
            alert(getParam());
        }
    });
    //貌似需要去手动删除变量param,这样可以吗?
    param=null;
}
f1("HelloWorld");

那么问题来了,是什么原因造成代码1成功打印HelloWorld的呢?


我没有系统的学习过js,哪里没有考虑到的地方还请大家指点。


更新:
模拟一下:代码3

<script type="text/javascript">
function f1(param){
    $.ajax({
        url:"",
        error:function(data){
            alert(param);
        }
    });
}
f1("HelloWorld");
</script>

成功打印HelloWorld,那为什么会出现param为undefined的情况呢?


再次更新:
问题代码与调试的过程 截图:
图片描述
可以确保的是,参数action传入到了catRecord函数中。
但可以看到,截图右侧中两个function函数中都没有action变量,或者action为undefined。


更新:
实在不好意思,花了大家这么多时间,再次谢谢大伙了。
我简答总结一下我的问题:
由于我在一个function中,变量的命名出了问题(到底是什么问题呢,1、语法上的问题我的确不懂2、在可读性上也相当不好),导致理应获取的变量获取不到。
然后我在查了一些js局部变量作用范围、js闭包、(还没有查到关于js变量加载机制)的资料后,利用闭包暂时解决了我上述的问题。
虽然问题解决了,但我总觉的这样做不是很好的方法,也许是思路本身就错了;这个问题一直在心里搁着,只好来sf向大家求教。
最后很多前辈指出了问题的所在,也有前辈指出了我X-YProblem的嫌疑=。=,虽然之前没听说过这个,但了解之后真心觉得不好意思。
再次谢过大家了!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情未る 2022-09-06 16:39:35

图片描述

下面声明的变量把参数覆盖了,所以你监视器里的actionfunctionvar声明的action,而不是参数action, 执行到这一句的时候 被var声明的action还没有赋值。所以是 undefined

另外提一点,楼主的提问在没更新截图之前,让我想到了XY-Problem

鹊巢 2022-09-06 16:39:35

代码1,3绝对不会出现undefined,代码2会出现null的情况。刚才看错了。

蓬勃野心 2022-09-06 16:39:35

這種特性叫做閉包。

參見:閉包的運用

閉包是一種特殊的物件,其中結合了兩樣東西:函數,和函數所建立的環境。環境由任意的局域變數所組成,這些變數是由在閉包建立的時間點上存在於作用域裡的所有變數。

function bind(fn, x) {
    return function(y) { return fn(x, y); }
}

例如此例,fn 是一個二元函數,bind 將其第一個參數固定,生成一個一元函數。

在 ES6 (JavascriptNext) 中,有一類 arrow function,不僅綁定局部變量,還綁定了 this:

function bind(fn, x) {
    return y => fn.call(this, x, y);
}

等價於

function bind(fn, x) {
    var self = this;
    return function(y) { return fn.call(self, x, y); }
}

這樣,調用 bind 時的 this,也會被傳遞到 fn。

var ex = { bind: bind };

var greet = ex.bind(function(x, y) { console.log(this, x, y); }, "hello");

greet("Mr. Closure"); // Object {bind: function} "hello" "Mr. Closure"

以上。


補充,針對樓上的錯誤答案:

undefined 是未賦值而不是被賦值成 undefined。

聲明並不會改變同一作用域下原有的值。var a = b 是 var a; a = b 的簡寫。var a 會被提前但並不影響同一作用域下原有的值。所以函數的參數又被重複聲明並不會受到影響。

如:

(function(x) {
    var x = x + 1;

    return x;
}(1));

// 2

但下面的則會影響:

var x = 1;

(function() {
    var x = x + 1;

    return x;
}());

// NaN
扛起拖把扫天下 2022-09-06 16:39:35
function f1(param){
    $.ajax({
        xxx:xxx,//参数省略
        success:function(data){
            alert(param);
        }
    });
}
f1("HelloWorld");

js里有作用域链的概念:即如果在当前作用域中找不到,会到上层作用域中查找,并逐层向上直到找到或者在最外层(即Window中)还是没找到,就会返回undefined。
然后第二个概念,闭包:简单说就是在函数中定义函数。闭包的特点是,被包含的子函数可以访问到外层函数的作用域。
结论:alert(param);中的param一定可以取到function f1(param)的形参param值。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文