循环内的javascript变量声明 /*测试范围问题*/ 对于(var i=1;i
我喜欢从中获得如此多的里程数 如果你需要帮助应用这个答案,请告诉我 编辑 当然可以。让我们看看您的原始代码循环内的javascript变量声明 /*测试范围问题*/ 对于(var i=1;i,javascript,variables,scope,Javascript,Variables,Scope,我喜欢从中获得如此多的里程数 如果你需要帮助应用这个答案,请告诉我 编辑 当然可以。让我们看看您的原始代码 /*Test scope problem*/ var func=function(no){ //verify no alert('setting '+no); //timeout to recheck setTimeout(function(){ alert('test '+no); }, 500); } for(var i=1;
/*Test scope problem*/
var func=function(no){
//verify no
alert('setting '+no);
//timeout to recheck
setTimeout(function(){
alert('test '+no);
}, 500);
}
for(var i=1; i<3; i++){
func(i);
}
看到那个匿名函数了吗?就是你传递到setTimeout()
的那个函数吗?它在计时器显示之前不会被调用,而在500毫秒时,循环已经退出
您希望的是no
被“就地”计算,但它不是-它是在调用函数时计算的。此时,no
为2
为了解决这个问题,我们需要一个在循环迭代期间执行的函数,该函数本身将返回一个函数,setTimeout()
可以按照我们期望的方式使用
//timeout to recheck
setTimeout(function(){
alert('test '+no);
}, 500);
由于我们创建了匿名函数并立即调用它,因此创建了一个新的作用域,我们可以在其中关闭变量。该作用域围绕value
,而不是no
。由于value
为每个循环接收一个新的(ahem)值,因此每个循环都有自己的值—我们希望它这样做
因此,当setTimeout()激发时,它正在执行从闭包函数返回的函数
我希望这能解释它。这与您的修复基本相同,但使用不同的语法来实现范围调整
setTimeout(function( value )
{
// 'value' is closed by the function below
return function()
{
alert('test ' + value );
}
}( no ) // Here's the magic
, 500 );
/*测试范围问题*/
对于(变量i=1;i<3;i++){
//声明变量
var no=i;
//验证否
警报(“设置”+否);
//重新检查超时
(功能(){
var n=否;
setTimeout(函数(){
警报(“测试”+n);
}, 500);
})();
}
Javascript没有词法作用域(for循环不会创建新的作用域),您的解决方案是标准的解决方案。另一种编写方法可能是:
/*Test scope problem*/
for (var i = 1; i < 3; i++) {
//declare variables
var no = i;
//verify no
alert('setting ' + no);
//timeout to recheck
(function() {
var n = no;
setTimeout(function() {
alert('test ' + n);
}, 500);
})();
}
forEach()是在ECMAScript 5中引入的,并出现在现代浏览器中,但不是IE中。不过,您可以使用它进行模拟。JavaScript没有块作用域,并且变量声明被提升。这些事实一起意味着您的代码相当于:
[1, 2].forEach(function(no){
//verify no
alert('setting '+no);
//timeout to recheck
setTimeout(function(){
alert('test '+no);
}, 500);
})
我也很想看到关于
no
的作用域的详细解释。@Daniel Bingham-no
的作用域是全局的,除非Trouts在函数中这样做。(循环不会在js中设置新的作用域。)@fig gnuton噢。这是一个简单的解释:D谢谢!是的,不知道这与这个问题有什么关系。你能解释一个C/Java开发人员仅仅学习Javascript的闭包吗?很好的答案,它认为不能完全解释它。我最初认为Javascript中的作用域总是在{}的范围内工作,所以这个问题。
[1, 2].forEach(function(no){
//verify no
alert('setting '+no);
//timeout to recheck
setTimeout(function(){
alert('test '+no);
}, 500);
})
var no;
/*Test scope problem*/
for(var i=1; i<3; i++){
//declare variables
no = i;
//verify no
alert('setting '+no);
//timeout to recheck
setTimeout(function(){
alert('test '+no);
}, 500);
}
var no;
/*Test scope problem*/
for(var i=1; i<3; i++){
//declare variables
no = i;
//verify no
alert('setting '+no);
//timeout to recheck
setTimeout( (function(num) {
return function() {
alert('test '+num);
};
})(no), 500);
}