JavaScript:词汇封闭还是其他什么?

Mat*_*y F 6 javascript

考虑这个脚本:

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
Run Code Online (Sandbox Code Playgroud)

不完全是预期的输出,但是当我更新到这个时:

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
Run Code Online (Sandbox Code Playgroud)

这似乎有效,我不知道为什么.任何人都可以开导我吗?谢谢

小智 2

查看http://jibbering.com/faq/notes/closures/

它将解释“其他内容”,并且可能解释您想了解的有关 JavaScript 变量和作用域如何工作的所有内容。JavaScript 使用“执行上下文”闭包,而不是“词法变量”闭包(编辑:它仍然是词法绑定,只是不一定如预期那样 - 见下文)。

在第一个示例中,相同的 obj内容被绑定了三次,或者更确切地说,单个绑定执行上下文的obj相同属性(编辑:规范不要求这样做,但将其称为属性是解释它的一种方式)是共享的!

var不“声明”变量(编辑:它是一个适用于整个作用域的注释,不受 {} 的影响,以下情况除外),并且function是人们如何引入新作用域 -> 新执行上下文(即为什么第二个示例按预期工作)。新范围通过function(或eval/类似)引入。

快乐编码。