Javascript 用于。。。在使用对象时,始终引用对象中的最后一个关键点

Javascript 用于。。。在使用对象时,始终引用对象中的最后一个关键点,javascript,scope,Javascript,Scope,我有以下代码: var obj = {"a" : "A", "b" : "B", "c" : "C"}; for( value in obj) { setTimeout(function() { console.log(value); }, 100); } 在控制台中运行该代码的结果是c被记录三次 为什么它总是引用setTimeout()中的最后一个键,如何让它在for循环中按顺序引用它们 它与范围有关,但我不能把我的头绕在它周围…你需要使用一个 这是因为调

我有以下代码:

var obj = {"a" : "A", "b" : "B", "c" : "C"};
for( value in obj) {
    setTimeout(function() { 
        console.log(value); 
    }, 100);
}
在控制台中运行该代码的结果是
c
被记录三次

为什么它总是引用
setTimeout()
中的最后一个键,如何让它在for循环中按顺序引用它们

它与范围有关,但我不能把我的头绕在它周围…

你需要使用一个

这是因为调用
setTimeout
回调函数时,
value
的值将发生更改

通过将其包装在匿名函数中,
value
的值不会改变,因为将为对象中的每个项创建一个新函数-JavaScript具有函数作用域而不是传统的块作用域。

您需要使用

这是因为调用
setTimeout
回调函数时,
value
的值将发生更改


通过将其包装在匿名函数中,
value
的值不会改变,因为将为对象中的每个项创建一个新函数-JavaScript具有函数作用域而不是传统的块作用域。

另一种选择,有时更干净,创建闭包的方法是创建一个单独的函数,该函数根据设置值返回超时函数:

function getTimeoutFunction(value) {
    return function() {
        console.log(value);
    };
}
for (value in obj) {
    setTimeout(getTimeoutFunction(value), 100);
}

创建闭包的另一种方法(有时更简洁)是创建一个单独的函数,该函数根据设置值返回超时函数:

function getTimeoutFunction(value) {
    return function() {
        console.log(value);
    };
}
for (value in obj) {
    setTimeout(getTimeoutFunction(value), 100);
}

对于obj中的每个元素,都有一个设置为obj元素的单个变量值。您的闭包有一个对该变量的引用,因此当封闭范围中的值更改时,它也会在闭包中更改。因此,在100毫秒后执行闭包后,值已分配给obj中的最后一项。要解决此问题,您需要通过添加另一个匿名函数来引入一个新的作用域,并将需要临时存储的值传递给该匿名函数:

var obj = {"a": "A", "b": "B", "c":"C"};
for( var value in obj) {
    (function(value) {
         setTimeout(function() {
             console.log(value);
         },100);
     })(value);
 }
或:

您需要围绕函数定义进行分析,因为如果“function”是一行中的第一个标记,javascript会将其视为命名函数声明,而不是函数表达式

从ECMAScript 5开始,使用闭包是在Javascript中引入新作用域的标准方法。但是,在ECMAScript 6(尚未最终确定或实现)中,可以使用let语句


p、 您可能应该将值声明为var,除非您在函数的其他地方这样做,否则您将创建一个全局变量。

对于obj中的每个元素,您有一个设置为obj元素的单个变量值。您的闭包有一个对该变量的引用,因此当封闭范围中的值更改时,它也会在闭包中更改。因此,在100毫秒后执行闭包后,值已分配给obj中的最后一项。要解决此问题,您需要通过添加另一个匿名函数来引入一个新的作用域,并将需要临时存储的值传递给该匿名函数:

var obj = {"a": "A", "b": "B", "c":"C"};
for( var value in obj) {
    (function(value) {
         setTimeout(function() {
             console.log(value);
         },100);
     })(value);
 }
或:

您需要围绕函数定义进行分析,因为如果“function”是一行中的第一个标记,javascript会将其视为命名函数声明,而不是函数表达式

从ECMAScript 5开始,使用闭包是在Javascript中引入新作用域的标准方法。但是,在ECMAScript 6(尚未最终确定或实现)中,可以使用let语句


p、 您可能应该将值声明为var,除非您在函数的其他地方这样做,否则您将创建一个全局变量。

是的,我的朋友,是的。jsfiddle是您的朋友伙伴!!!是的,我的朋友,是的,是的。jsfiddle是你的朋友!!!可能的复制的伟大解释!工作非常出色,学到了一些新东西。谢谢很好的解释!工作非常出色,学到了一些新东西。谢谢