【问题标题】:“var” variables, "this" variables and "global" variables - inside a JavaScript Constructor“var”变量、“this”变量和“global”变量 - 在 JavaScript 构造函数中
【发布时间】:2012-08-11 00:48:02
【问题描述】:

在我最后一个问题之后,这个问题对我来说更准确:

示例:

function Foo() {
    this.bla = 1;
    var blabla = 10;
    blablabla = 100;
    this.getblabla = function () { 
        return blabla; // exposes blabla outside
    }
}
foo = new Foo();

我现在的理解:

this.bla = 1;     // will become an attribute of every instance of FOO.
var blabla = 10;  // will become a local variable of Foo(will **not** become an attribute of every instance of FOO), which could be accessed by any instance of FOO - only if there's a method like "this.getBlabla". that's a "closer" ?
blablabla = 100;  // will define a **new** (or change if exist) global(window) variable.

我理解正确吗?

另外 - 如果我在承包商中包含 var blabla = 10; 和使用它的 getblabla 函数,那么对于 Foo("foo"...) 的每个实例,将在内存中保存一个 Foo 承包商函数包括这个“私有”变量。还是与私有变量的位置相同的 Foo 函数 - 对于 Foo 的 ALL 实例(如“foo”)?

【问题讨论】:

  • 您的前三个断言是正确的。我不完全遵循您对最后一个问题的要求。你能澄清一下吗?您也可以尝试名称不相似的变量吗?很难跟上。谢谢。
  • 这对我来说也很复杂。我的意思是 - 这是一个关闭,对吧?它是一个承包商——所以,对于 Foo 的每个实例,内存中都会有一个新的 Foo 闭包?这东西是怎么工作的?谢谢。

标签: javascript constructor this var


【解决方案1】:

只是为了关注范围,我将运行这个示例,(使用更清晰的变量)然后,我会将它连接回您的变量。

var x = "Global scope";
var y = "Not changed.";

function Foo() {
    this.x = "Attribute of foo";
    var x = "In foo's closure";
    y = "Changed!"
    this.getX = function () { 
        return x;
    }
}

// do some logging

console.log(x); // "Global scope"
console.log(y); // "Not changed"
foo = new Foo();
console.log(y); // "Changed!"
console.log(foo.x); // "Attribute of foo"
console.log(x); // "Global scope"
console.log(foo.getX()); // "In foo's closure"

行:this.x 等价于this.bla,它定义了Foo 对象的外部可用属性。 y 等价于blablabla=100,然后 foo 中的 x 等价于您在 foo 中的 blablabla。这是一个非常粗略的jsfiddle,你可以跑去看看。

【讨论】:

    【解决方案2】:

    你说的都是对的。 (当然Strict Mode中的blablabla赋值会抛出错误。

    后半部分,构造函数没有什么特别之处。它就像任何其他函数一样,它创建一个闭包,只要它被引用(在这种情况下是 this.getblabla 的生命周期),它就会持续存在。

    举个例子:

    function initBlaBla() {
        var blabla = 10;
        this.getblabla = function () { 
            return blabla; // exposes blabla outside
        }
    }
    
    function Foo() {
        this.bla = 1;
        blablabla = 100;
        initBlaBla.call(this);
    }
    
    foo = new Foo();
    

    这里,Foo 构造函数不会形成闭包,它的作用域会立即释放。另一方面,initBlaBla 创建了一个闭包。有趣的是,编译器可能会看到 blabla 从未被写入并优化 this.getblabla 以始终返回 10 并且从不保存闭包范围。当您在闭包内的函数中中断执行并尝试读取它没有在内部引用的值时,可以看到这一点。

    如果您调用以下任何方法,闭包范围将被释放并排队等待垃圾回收:

    delete foo.getblabla;
    foo.getblabla = "Anything!";
    foo = "Anything else.";
    

    【讨论】:

      【解决方案3】:

      是的,你明白了!
      至于问题的第二部分,这都是关于继承的,就像(全局)窗口与其范围内定义的函数之间的关系(想想根)。所以你没有重新指定的所有东西,都会被查找到祖先。

      这是 Crockford 的 tremendous good video,他解释得非常好。

      【讨论】:

        猜你喜欢
        • 2011-05-20
        • 1970-01-01
        • 2012-08-10
        • 1970-01-01
        • 2023-03-02
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 2010-11-26
        相关资源
        最近更新 更多