2012-08-14 55 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

相關問題