2012-06-14 59 views
0

我有了一個公共的setter/getter函數私有變量一類的局部變量:訪問使用原型

function Circle(rad) { 
    var r = rad; 

    this.radius = function(rad) { 
     if(!arguments.length) return r; 
     r = rad; 
     return this; 
    } 
} 

var shape = new Circle(10); 
console.log(shape.radius()); // 10 
shape.r = 50; 
console.log(shape.radius()); // 10 

我怎麼能複製這個使用Object.prototype?或者,我何時想使用閉包而不是Object.prototype?這是我能想出的最接近的,但正如你所看到的,你可以直接改變財產。

function Circle(r) { 
    this.r = r; 
} 

Circle.prototype.radius = function(r) { 
    if(!arguments.length) return this.r; 
    this.r = r; 
    return this; 
}; 

var shape = new Circle(10); 
console.log(shape.radius()); // 10 
shape.r = 50; 
console.log(shape.radius()); // 50 
+2

你或者你不想從外面設置它? –

+0

我希望可以通過我定義的公共getter/setter函數來訪問它。我不希望課堂以外的任何人直接公開訪問變量。 – Wex

+0

「我如何使用類的原型對象來複制它?」我真的不明白這個問題。你爲什麼要用一種可能不應該實現它的語言功能複製某種行爲? – millimoose

回答

4

如果您打算使用原型來存儲對象的屬性,則可以從任何具有對該對象的引用的代碼訪問它們。做你想做的事是不可能的。

然而,很多JS開發者做的僅僅是名稱與一個領先的下劃線,讓其他人知道不惹它私人性質,但它不會給你超過建議任何真正的保護

理由基於採用封閉方式

  • 真正的私有變量,確信沒有人會亂用陰部

理由使用原型

  • 更少的內存使用(沒有關閉每個實例)
  • 更容易調試(屬性對象本身上可見)
  • 允許猴子修補

讀者:請根據您認爲是最佳解決方案的理由編輯答案。

+0

僅僅堅持我的第一個代碼版本有什麼缺點嗎?或者有沒有其他方法可能會更好? – Wex

+1

不足之處在於爲每個對象創建了一個新的閉包,即額外的內存。我對私人財產沒有偏執,我用下劃線來表示私人財產。如果有人在課堂以外觸及它,我就把它們砸在頭上,直到他們學會不要! –

+0

因此,最好使用Object.prototype來創建閉包? – Wex

0

我發現你的第一個圓很奇怪。如果你重寫這樣的:

 function Circle(rad) { 
      var r = rad; 

      this.radius = function(rad) { 
       if(rad){r = rad;} 
       return r; 
      } 
     } 

我認爲它現在就是你的意思。 r是私人的,半徑作爲一個吸氣/定位器功能。 這樣設置R:

shape.r = 50; 

就沒有意義了,因爲你的第一圈沒有一個屬性R,它只有一個局部範圍的變量r。它應該引起某種錯誤。

我看不到在Circle的第二個版本中使用原型的方法,因爲原型鏈中的函數無法訪問在Circle對象中創建的變量。無論如何,在你的第二個版本中,r是Circle的一個屬性,而不是函數體中的私有作用域變量。

+1

如果將半徑設置爲0會怎樣?您的代碼更改將忽略它。 OP中的方法沒有任何問題,您的建議與真實問題無關。 –

+0

由於Javascript的動態特性,設置'shape.r = 50'會創建一個值爲'50'的公共屬性'r'。 – Wex

+0

爲了解釋Wex提到的,JS允許你在任何對象上創建屬性。 'shape.r = 50'只是在對象上設置一個屬性(並且該屬性將永遠不會被讀取) –