2012-08-14 81 views
5

在我的最后一个问题后,这个人是更准确的对我说:“VAR”变量“这个”变量和“全局”变量 - JavaScript构造

例如:

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

+0

你的前三个断言是正确的。我并不完全按照你最后一个问题的要求。你能澄清吗?你也可以尝试变量的名字没有这么相似吗?这很难遵循。谢谢。 – Brad 2012-08-14 16:59:57

+0

对我来说也很复杂。我的意思是 - 关闭了,对吧?而且它是一个承包商 - 因此,对于Foo的每一个实例,内存中都会有新的Foo关闭?这些东西如何工作?谢谢。 – Daniel 2012-08-14 17:03:23

回答

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

是的,你明白了!
至于问题的第二部分,全部是关于继承,就像(全局)窗口和其范围中定义的函数(认为根)之间的关系一样。因此,所有你没有重新指定的东西,都会被抬头看向祖先。

这是克罗克福德的tremendous good video,他很好地解释它。

2

你所说的一切都是正确的。 (当然,错误将在blablabla分配中Strict Mode抛出。

在下半年,有什么特别的构造函数,它只是就像任何其他的功能,因为它创建了持续长达一个封闭如

其引用(在这种情况下的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另一方。韩d创建一个闭包。有趣的是,编译器可能会看到blabla永远不会写入并优化this.getblabla以始终返回10并永不保存闭包范围。当你在一个闭包中的函数中断开执行并尝试读取它没有内部引用的值时,可以看到这一点。

的封闭范围将得到释放,并排队等待垃圾收集,如果你调用任何操作:

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