“var”变量,“this”变量和“global”变量 - 在JavaScript构造函数中

时间:2012-08-14 16:56:21

标签: javascript constructor this var

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

示例:

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”)?

3 个答案:

答案 0 :(得分:6)

只关注范围,我将通过这个例子,(更清晰的变量)然后,我将它连接回你的变量。

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你可以看到这个。

答案 1 :(得分: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.";

答案 2 :(得分:1)

是的,你明白了!
至于问题的第二部分,它就是继承,就像(全局)窗口和它的范围中定义的函数之间的关系一样(思考根)。所以你不重新指定的一切都会被抬头看看祖先。

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