2012-08-14 54 views
10

例如:JavaScript构造函数中的“var”变量会发生什么?

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

foo = new Foo(); 

原题:

我知道,喇嘛将被分配到富的每一个实例。 blabla会发生什么?

新的问题:

我现在明白了:

this.bla = 1;  // will become an attribute of every instance of FOO. 
var blabla = 10; // will become a local variable of Foo(**not** 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". 
blablabla = 100; // will define a **new** (or change if exist) global(window) variable. 

        Did i understand correctly? 
+0

你编辑的例子是正确的 - 除了'blabla'对'Foo'的每一个实例都是唯一的。所以如果'Foo'看起来像'function Foo(number){var blabla = number; this.bla = 37; this.getBlaBla = function(){return blabla; }; }'然后'myFoo = new Foo(32);''和'yourFoo = new Foo(47);'对于'.getBlaBla()'会有完全不同的值。 'myFoo.getBlaBla()=== 32; yourFoo.getBlaBla()=== 47;'重要的是要记住,即使它是一个“本地范围的值”,它对于每个实例都是唯一的,并且不会成为任何Foo读/写的相同值以共同的方式。 – Norguard 2012-08-16 13:48:26

回答

8

任何内部的方法,你给this - 即:this.method = function() {};而里面你的Foo构造函数,是所有将不得不在参考对于Foo对象的每个实例都是唯一的。

function Wallet() { 
    var balance = 0; 
    this.checkBalance = function() { return balance; }; 
    this.depositAmount = function (amount) { balance += amount; }; 
} 


var wallet = new Wallet(); 
wallet.checkBalance(); // 0 
wallet.depositAmount(3); 
wallet.checkBalance(); // 3 

但是它完全免受外部钱包访问的影响,除非您从特权功能返回给某人。

wallet.balance; // undefined; 

(兴趣增加位 - 如果balancestring,一个numberboolean,即使你回吧,不会给人们编辑权限,甚至永久性观看访问 - 标变量是按值传递的,所以您只是在时间处传递余额的值 - 但如果余额是objectfunctionarray,则他们可以永久访问以修改废话您的内部工作)

注意:方法HAVE被分配给构造函数内部使其工作。 原型不能访问内部变量。 稍后添加方法不会让他们访问内部变量。

这意味着每个实例都会占用更多内存,因为每个实例都有自己的方法副本,并拥有自己的变量副本。 但是,如果你在做什么需要私人数据,这将是一个很好的方式来获得它。

+0

谢谢。所以如果我做了一个anoter实例“var myOtherWallet = new Wallet();那么它会在另一个包含另一个”var balance = 0“的内存中关闭? – Daniel 2012-08-14 17:21:43

+0

@ user1598423:是的,每次运行构造函数时它都会创建一个新的局部变量,当你将方法与对象相关联时,每个对象都有自己的方法实例,并有自己的闭包。 – Guffa 2012-08-14 17:38:53

2

它将成为当地Foo()(认为 '私有')变量。这意味着您无法在Foo()之外访问它。

function Foo() { 
    this.bla = 1; // this becomes an extension of Foo() 
    var blabla = 10; // this becomes a "Local" (sort of like a 'private') variable 
} 

您可以用Foo方法暴露它(通过返回它)。

function Foo() { 
    var blabla = 10; // local 

    this.getBlabla = function() { 
     return blabla; // exposes blabla outside 
    } 
} 

现在美孚()以外:

var FooBar = new Foo(); 

var what_is_blabla = FooBar.getBlabla(); //what_is_blabla will be 10 

jsFiddle demonstration

+2

这是一个**本地**变量。我会避免使用术语“私人”,因为在讨论其他语言(JavaScript没有的东西)的可见性时会使用它。 – 2012-08-14 15:23:40

+1

你可以添加其他暴露的函数可以访问'blabla'。所以通过加入'this.method = function(){return blabla; };',可以检索'blabla'的内容。 – Sirko 2012-08-14 15:24:11

+1

好的呼叫菲利克斯,在技术上忘了那里没有任何“私人”。实际上只是添加了Sirko的东西! – 2012-08-14 15:26:17

1

该变量为局部的构造,也不会是范围以外访问(无论是通过this或以其他方式),除非它被封闭捕获。

1

在用作构造函数的函数内声明的变量将与任何函数内用var声明的所有其他变量一样,仅在执行该函数期间才可见(除非该值是使用闭包关闭的)。

换句话说,blabla是功能外有效无形:

var foo = new Foo(); 
console.log(foo.bla);  // 1 
console.log(foo.blabla); // throws NameError 

通过定义关闭了这些变量函数,它们成为最接近的JavaScript具有“私有”变量:

function Foo() { 
    this.bla = 1; 
    var private = 1; 

    this.increment = function() { 
     ++private; 
    } 

    this.getPrivateValue = function() { 
     return private; 
    } 
} 

foo = new Foo(); 
console.log(foo.bla);    // 1 
foo.bla = 6;       // legal 
console.log(foo.bla);    // 6 
console.log(foo.getPrivateValue()); // 1 
// console.log(foo.private);   // would throw an error 
foo.increment();      // legal 
console.log(foo.getPrivateValue()); // 2 
// foo.getPrivateValue() = 5;  // syntax error. Still can't reassign to private no matter what you try! 
-2

blabla几乎可以被认为是Foo的私人成员。

查看this来自Douglas Crockford的文章。

0

如果您不使用var关键字,则“blabla”将成为全局变量。在代码中的其他地方,如果你也使用blabla without var,它也将是全局的,并且你可能会无意中更改blabla的其他实例并在你的代码中引入无意识的错误。 “var”将变量放在当前范围中,所以在上面的情况下,它只能由Foo访问。

5

在你的例子中blabla是一个局部变量,所以当构造函数结束时它将消失。

如果声明构造内部的功能,它使用了可变的,那么变量将是闭合该功能的一部分,和(即通常只要对象),只要生存作为功能:

function Foo() { 
    this.bla = 1; 
    var blabla = 10; 

    this.getBlabla = function() { 
    alert(blabla); // still here 
    } 
} 
+1

您可能表示该变量只要*函数*或*函数对象*就存在,以便将其与构造对象区分开来。 – 2012-08-14 15:34:55

+1

@amnotiam:是的,你说得对,那是更具描述性的。 – Guffa 2012-08-14 15:39:38

+0

所以只有在承包商内使用“this”的变量才会成为实例的属性?“var blabla = 10”将只是Foo的本地属性 - 只有在使用它的“this”方法时才会存在? – Daniel 2012-08-14 16:38:29

相关问题