Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
循环内的javascript变量声明 /*测试范围问题*/ 对于(var i=1;i_Javascript_Variables_Scope - Fatal编程技术网

循环内的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);
}