5

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

例子:

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 的所有实例(如“foo”)?

4

3 回答 3

7

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

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"

line:this.x等价于this.bla,它定义了一个Foo对象的外部可用属性。y等价于blablabla=100然后xwithin foo 等价于你blablabla的inner foo。这是一个非常粗糙的jsfiddle,您可以运行它来查看。

于 2012-08-14T17:30:32.307 回答
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.";
于 2012-08-14T17:28:44.553 回答
1

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

这是Crockford制作的一个非常棒的视频,他解释得非常好。

于 2012-08-14T17:10:26.323 回答