2012-02-02 81 views
2

覆蓋例如如何在在公共職能

var MyClass = function(){ 

    var that = this; 

    var my_var = "I want this"; 

    var another_var = "this one is easy"; 

    this.aPublicFunc = function(my_var){ 

    console.log(my_var); // logs "I don't want this"; 
    console.log(another_var); // logs "this one is easy"; 
    console.log(this.my_var); // logs undefined which makes sense as the this context is the context of the calling function. 
    console.log(that.my_var); // logs undefined 
    }; 
}; 

var an_object = new MyClass(); 
var an_object.aPublicFunc("I don't want this"); 
+1

爲什麼你不重命名你的第二個'my_var'? – deceze 2012-02-02 12:18:44

+1

答案是:你沒有。更好地命名你的變量和函數參數。 – 2012-02-02 12:21:12

+2

'my_var'和'another_var'是你的例子中的全局變量。全局變量和局部變量不是神奇地成爲你創建的對象的屬性,所以'that.my_var'不能工作,除非你明確地指定它。在你的例子中,當調用'an_object.aPublicFunc(...)''this'時也指'that'。 – 2012-02-02 12:21:56

回答

2

像你一樣擁有my_var的私有變量只能從構造函數中的代碼和其範圍內定義的函數(如aPublicFunc())中調用。而且,要訪問它們,您必須使用正常的JavaScript引用。當您使用相同的名稱定義參數爲aPublicFunc()時,您將隱藏該外部範圍變量,並且沒有辦法按照定義來達到它。這些私有變量不是對象的成員,它們是在閉包中捕獲的變量。在JavaScript中,在閉包中訪問變量的唯一方法是從閉包範圍內的代碼,如果沒有任何內容覆蓋它們的名稱,則只能覆蓋它們。

您的簡單解決方案是將參數或局部變量的名稱更改爲略有不同的名稱。如果你真的希望他們看起來很相似,然後把下劃線在這樣其中的一個前端:

var MyClass = function(){ 

    var that = this; 
    var _my_var = "I want this"; 
    var _another_var = "this one is easy"; 

    this.aPublicFunc = function(my_var){ 

    console.log(_my_var); // logs "I want this"; 
    console.log(_another_var); // logs "this one is easy"; 
    console.log(my_var); // logs "I don't want this" 
    }; 
}; 

var an_object = new MyClass(); 
var an_object.aPublicFunc("I don't want this"); 

或使其論點這樣一點更加明顯:

var MyClass = function(){ 

    var that = this; 
    var my_var = "I want this"; 
    var another_var = "this one is easy"; 

    this.aPublicFunc = function(new_my_var){ 

    console.log(my_var); // logs "I want this"; 
    console.log(another_var); // logs "this one is easy"; 
    console.log(new_my_var); // logs "I don't want this" 
    }; 
}; 

var an_object = new MyClass(); 
var an_object.aPublicFunc("I don't want this"); 

你可以看到這最後一個工作在這裏:http://jsfiddle.net/jfriend00/Jeaaz/

+0

謝謝,清楚的解釋。 – SystemicPlural 2012-02-15 08:50:33

2

不重寫公共函數訪問私有變量。它使得代碼不易讀和更令人困惑。

+0

在這種情況下,它是一個二傳手。所以有相同的名字是有道理的。但如果我看不到它,我無法設置它。 – SystemicPlural 2012-02-02 12:43:34

+0

即便如此,它仍然讓IMO感到困惑。它們並不代表同一件事,所以將它們稱爲同一件事情是有道理的。該參數表示一個新值/一個輸入值,而來自外部範圍的其他my_var表示該對象的舊/當前狀態。假設你設法從外面讀取my_var,你會怎麼知道,單獨看着那條線,不管你是在讀舊的/當前的狀態還是正在讀取新的狀態?如果名稱/參考中的某些內容將兩者區分開來,它可幫助提高可讀性。 newvalue,currentvalue,state.value等 – Supr 2012-02-02 13:03:49

+0

在其他語言中,你會使用this.my_var = my_var,不幸的是,這裏唯一的辦法就是讓my_var成爲public,這正是我想要避免的。它是私人的,也避免了在其他地方訪問它的問題。 – SystemicPlural 2012-02-02 13:37:20