2012-06-13 39 views
1

我是看着Static variables in JavaScript,我發現了一些我以前也見過,該函數的定義和函數定義的函數原型更新後爲什麼在函數定義之外引用靜態變量(函數屬性)?

function MyClass() { // constructor function 
    //function definition here 
} 

//now add a (static?) method *outside* the function definition 
MyClass.prototype.publicMethod = function() { 
    alert(this.publicVariable); 
}; 

//add a static property *outside* the function definition 
MyClass.staticProperty = "baz"; 

我的問題是 - 爲什麼不將它們定義在函數定義裏面,像這樣:

function MyFunc(){ 
    MyFunc.staticVar = 1; 
    //static method showing static var 
    MyFunc.showVarStatic = function(){ 
     alert(MyFunc.staticVar); 
    } 
    //instance method referring to static var 
    this.showVarInstance = function(){ 
     alert(MyFunc.staticVar); 
    } 
    //instance method - doesn't change static var 
    this.inc1 = function(){ 
     this.staticVar += 1;//no such property 
    } 
    //static method, changes var 
    this.inc2 = function(){ 
     MyFunc.staticVar += 1;//increments static property 
    } 
    } 

這似乎在IE8,FF和Chrome中的預期行爲。這僅僅是個人喜好/風格的東西嗎?我喜歡它,因爲我的整個功能都包含在大括號中。

[編輯:做更多的閱讀和試​​驗後,我有更好的理解如何JavaScript函數是構造器,它們從如何不同。例如,C#類 - 這裏的一些代碼我用來證明這一點]

//this is deceiving, notSoStaticVar won't exist until MyFunc1 has been run 
//and then it will be reset whenever MyFunc1 (a constructor) is run 
function MyFunc1(){ 
    MyFunc1.notSoStaticVar = "I belong to MyFunc1"; 
    this.instanceVar = "I belong to instances of MyFunc1"; 
} 

//this code will be run inline one time, 
//so the static property of MyFunc2 will exist 
//(I like how all the functionality is in one code block, but it's kind of messy) 
MyFunc2 = (function(){ 
    var temp = function(){ 
     this.instanceVar = "I belong to an instance of MyFunc2"; 
    } 
    temp.staticVar = "I belong to MyFunc2"; 
    return temp; 
})(); 

//this seems to be equivalent to MyFunc2, but the code is cleaner 
MyFunc3 = function(){ 
} 
MyFunc3.prototype.instanceVar = "I belong to an instance of MyFunc3"; 
MyFunc3.staticVar = "I belong to MyFunc3"; 

//tests 
console.log(MyFunc1.notSoStaticVar);//undefined! 
var a = new MyFunc1(); 
console.log(MyFunc1.notSoStaticVar);//"I belong to MyFunc1" 
console.log(a.instanceVar);//"I belong to instances of MyFunc1" 
MyFunc1.notSoStaticVar = "I will be changed when another instance of MyFunc1 is created"; 
console.log(MyFunc1.notSoStaticVar);//"I will be changed when another instance of MyFunc1 is created" 
var b = new MyFunc1(); 
console.log(MyFunc1.notSoStaticVar);//"I belong to MyFunc1" - was reset by constructor! 

//now test MyFunc2 
console.log(MyFunc2.staticVar);//"I belong to MyFunc2" 
MyFunc2.staticVar = "I am not affected by the construction of new MyFunc2 objects"; 
var c = new MyFunc2(); 
console.log(c.instanceVar);//"I belong to an instance of MyFunc2" 
console.log(MyFunc2.staticVar);//"I am not affected by the construction of new MyFunc2 objects" 

//now test MyFunc3 
console.log(MyFunc3.staticVar);//"I belong to MyFunc3" 
MyFunc3.staticVar = "I am not affected by the construction of new MyFunc3 objects"; 
var d = new MyFunc3(); 
console.log(d.instanceVar);//"I belong to an instance of MyFunc3" 
console.log(MyFunc3.staticVar);//"I am not affected by the construction of new MyFunc3 objects" 

//interesting 
console.log(c);//"temp" <-- not really intuitive! 
console.log(d);//"MyFunc3" <-- makes sense 
+1

從您在示例中編寫的內容中,我想了解原型如何工作可能會有所幫助。您是否熟悉原型繼承的工作方式,或者對快速瀏覽有幫助? –

+0

我已經閱讀過有關原型,但從來沒有真正與它們混淆過 - 並沒有真正想過原型和靜態變量(或方法)之間的關係。在進一步的思考和實驗中,我可以看到如何使用原型並獲得某種靜態變量的惰性初始化,但該變量將始終由一個實例初始化......我從C#透視圖,並意識到一些有趣的差異。我的例子中的 – Aerik

回答

1

因爲這會爲每個對象實例添加獨特的功能。這會消耗額外的內存開銷,而這通常不是必需的。

它在某些情況下可能很有用,例如函數應該引用局部變量,但如果情況並非如此,則應該放在原型上。

此外,靜態的將不斷被覆蓋。

+0

,是不是MyFunc.somevar與MyFunc.prototype.somevar相同? – Aerik

+0

@Aerik:沒有。功能是對象,所以你可以直接給它們添加屬性,就像任何其他對象一樣。所以你用'MyFunc.somevar'做什麼是直接添加屬性到函數。它對使用該函數創建的對象沒有影響。但是添加像MyFunc.prototype.somevar這樣的屬性可以使'MyFunc'創建的所有對象都可以使用'somevar'屬性。 – 2012-06-13 14:24:53

2

總之:表現。

在函數內部定義它們會在您每次調用構造函數時重新定義它們。

雖然這會像預期的那樣行事,但這只是沒有理由的開銷。

相關問題