作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下代码:
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 -loop 迭代。但这是为什么呢?) 这是我的错误。该代码之所以有效,是因为第二个和第一个 i
相同!a[ i ]
的引用的方式编写 bb()
,这样我就不必使用索引?谢谢!
最佳答案
您需要记住,JavaScript 没有 block 作用域(好吧,无论如何还没有, ES6 is working that in with let
),相反,一切都在“函数”级别。也就是说,所有变量的作用域都是其最新的函数定义。
变量是使用 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() 完成的任务,但你是通过使用 x 来“存储对 a[ i ] 的引用”。也许你有更具体的例子?
关于javascript - JS : Which/How are variables stored in closures?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27359918/
我是一名优秀的程序员,十分优秀!