考虑这个脚本:
function Obj(prop) {
this.prop = prop;
}
var NS = {
strings: ['first','second','third'],
objs: [],
f1: function() {
for (s in this.strings) {
var obj = new Obj(this.strings[s]);
obj.f2 = function() {
alert(obj.prop);
}
this.objs.push(obj);
}
}
}
NS.f1();
NS.objs[0].f2(); // third
NS.objs[1].f2(); // third
NS.objs[2].f2(); // third
不完全是预期的输出,但是当我更新到这个时:
function Obj(prop) {
this.prop = prop;
}
var NS = {
strings: ['first','second','third'],
objs: [],
f1: function() {
for (s in this.strings) {
var obj = new Obj(this.strings[s]);
this.wire(obj); // replaces previous function def
this.objs.push(obj);
}
},
wire: function(obj) {
obj.f2 = function() {
alert(obj.prop);
} // exact same code and function def as the first example
}
}
NS.f1();
NS.objs[0].f2(); // first
NS.objs[1].f2(); // second
NS.objs[2].f2(); // third
这似乎有效,我不知道为什么。任何人都可以开导我吗?感谢
答案 0 :(得分:2)
查看http://jibbering.com/faq/notes/closures/。
它将解释“其他内容”以及您可能想知道的JavaScript变量和范围如何工作的所有内容。 JavaScript使用“执行上下文”闭包,而不是“词法变量”闭包(编辑:它仍然是一个词法绑定,只是不一定如预期 - 见下文)。
在第一个示例中,相同的 obj
被绑定了三次,或者更确切地说,相同的obj
属性(编辑:规范不需要这个,但是调用单一绑定执行上下文是共享的一种属性解释方法!
var
没有“声明”变量(编辑:它是一个适用于整个范围的注释,不受{}的影响,除了以下内容之外)function
是如何一个人可以引入新的范围 - >新的执行上下文(这就是第二个示例按预期工作的原因)。 function
(或eval
/类似)引入了新的范围 。
快乐的编码。
答案 1 :(得分:1)
...在单个闭包中只有一个obj,分配3次
...最终在三个闭包中加上3个obj(加上f1也有一个闭包),每个闭包一次
关于JS的一个有趣的事情可能有所帮助:以下两个函数做同样的事情:
function a1() {
var a,b,c;
a = 1;
b = 2;
c = 3;
}
function a2() {
a = 1;
b = 2;
c = 3;
var a,b,c;
}
var
声明始终在函数级范围内运行,无论函数在何处或嵌套在内部块中有多深。