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是你的朋友!!!可能的复制的伟大解释!工作非常出色,学到了一些新东西。谢谢很好的解释!工作非常出色,学到了一些新东西。谢谢