请考虑以下代码:
var a = [ { a: 'I' }, { a: 'II' }, { a: 'III' } ];
for( var i=0; i<a.length; i++ ){
var j = i;
var x = a[ i ];
x.bb = function(){
x.b = "-" + x.a + "-";
}
x.cc = function(){
a[ i ].c = "-" + a[ i ].a + "-";
}
x.dd = function(){
a[ j ].d = "-" + a[ j ].a + "-";
}
}
for( var i=0; i<a.length; i++ ){
a[i].bb();
a[i].cc();
a[i].dd();
}
console.log( a );
将导致(功能遗漏):
[ { a: 'I', c: '-I-' },
{ a: 'II', c: '-II-' },
{ a: 'III', b: '-III-', d: '-III-', c: '-III-' } ]
所以只有cc()做我想做的事。
我现在的问题是:
i
存储为常量,而j
和x
存储为对for循环迭代时更改的局部变量的引用。但为什么会这样? ) 我的错误。代码只起作用,因为第二个和第一个i
相同!bb()
的形式存储对a[ i ]
的引用,以便我不必使用索引?谢谢!
答案 0 :(得分:2)
你需要记住,JavaScript没有块范围(好吧,还没有,ES6 is working that in with let
),相反,一切都在&#34;功能&#34;水平。也就是说,所有变量的范围都限定在最近的函数定义中。
使用var
语句声明变量,根据您的代码,您拥有的每个变量都限定为此代码的外部容器。换句话说,如果此代码是在Node模块中,此处的所有变量都作用于整个模块。因此,尽管在for
循环中定义的函数是闭包(因为所有JS函数都是闭包),但它们仍然只是使用模块中定义的变量,因为JS不需要进一步查看
为了说明问题1的答案,请考虑以下事项:
var o = {};
var x = 1;
function foo() {
var x = 2;
o.bar = function() {
console.log(x);
}
}
o.bar(); // will output "2" because of the closure created in `foo()`
至于你的第二个问题,因为a [i]是一个对象,你赋予该对象的任何变量(在这种情况下,x
)将是一个引用,所有引用都将指向同一个对象在记忆中。我不是你用bb()
试图完成的事情,但你是&#34;存储对[i]&#34;的引用。使用x
。也许你有一个更具体的例子?