【Web前端问题】关于js中局部变量的作用范围

如下代码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的嫌疑=。=,虽然之前没听说过这个,但了解之后真心觉得不好意思。

再次谢过大家了!

回答:

图片描述

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

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

回答:

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

回答:

這種特性叫做閉包。

參見:閉包的運用

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

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

回答:

function f1(param){

$.ajax({

xxx:xxx,//参数省略

success:function(data){

alert(param);

}

});

}

f1("HelloWorld");

js里有作用域链的概念:即如果在当前作用域中找不到,会到上层作用域中查找,并逐层向上直到找到或者在最外层(即Window中)还是没找到,就会返回undefined。

然后第二个概念,闭包:简单说就是在函数中定义函数。闭包的特点是,被包含的子函数可以访问到外层函数的作用域。

结论:alert(param);中的param一定可以取到function f1(param)的形参param值。

以上是 【Web前端问题】关于js中局部变量的作用范围 的全部内容, 来源链接: utcz.com/a/143349.html

回到顶部