【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的嫌疑=。=,虽然之前没听说过这个,但了解之后真心觉得不好意思。
再次谢过大家了!
回答:
下面声明的变量把参数覆盖了,所以你监视器里的action
是function
里var声明的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