代码之家  ›  专栏  ›  技术社区  ›  Matty F

JavaScript:词法闭包还是别的什么?

  •  6
  • Matty F  · 技术社区  · 15 年前

    考虑一下这个脚本:

    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
    

    这似乎管用,我也不知道为什么。有人能启发我吗?谢谢

    2 回复  |  直到 15 年前
        1
  •  2
  •   user166390 user166390    15 年前

    退房 http://jibbering.com/faq/notes/closures/ .

    在第一个例子中 相同的 obj 目标 属性(编辑:规范不要求这样做,但将其称为属性是解释它的一种方法) 单绑定执行上下文

    var 不“声明”变量(编辑:它是应用于整个作用域的注释,不受{}的影响,但以下情况除外)并且 function 是如何引入新的作用域->新的执行上下文(这就是第二个示例按预期工作的原因)。新作用域是 只有 引入 功能 eval /类似)。

    快乐的编码。

        2
  •  1
  •   DigitalRoss    15 年前

    一层

    …一个闭包中只有一个obj,它被分配了3次

    …最终在三个闭包中有三个obj(加上f1也有一个obj),每个obj被分配一次

    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