2011-11-18 74 views
0

我知道使用原型的一個結果是所有添加的屬性和方法都將公開。這不是一個太大的問題,因爲我使用命名約定來區分內部和公共接口。所以是的,一切仍然是在技術上公衆。我應該在原型中添加* internal *屬性嗎?

難道是最好只加所有方法和屬性的原型 - 甚至打算是內部的 - 而不是隻增加公共方法/屬性的原型,並動態地創建內部使用this.property = value構造函數內的屬性。

看起來,因爲無論如何一切都將公開,所以我們不妨也爲原型添加內部屬性。

我知道使用閉包創建私人範圍。我的問題不是關於如何創建真正的私有屬性(這意味着拋棄原型,因爲任何這些方法都不具有內部訪問權限),而是關於使用原型時的最佳實踐。

function MyObjectA() { 
    this.myInternalProp_ = 5; 
    // ... 
} 

MyObjectA.prototype.myPublicProp = "Hello"; 

function MyObjectA() { 
    // ... 
} 

MyObjectA.prototype.myPublicProp = "Hello"; 
MyObjectA.prototype.myInternalProp_ = 5; 
+0

你能提供一個代碼示例? –

+0

我沒有看到問題是什麼。你只是問你是否應該使用可用於信息隱藏的語言結構,或者如果你不應該? –

+0

@RichardJPLeGuen問題是這樣的。我們是否應該避免在構造函數中動態創建新屬性。我應該把所有東西都放在原型上。這種方式不會動態創建屬性;也就是在原型成型之後。例如,做這個。myNewProp = value'調用我的對象的引擎模型,並且它必須重建它的隱藏類。這不是我主要關心的問題,因爲我很好奇人們對一致性和維護角度的看法。 – Peter

回答

1

在原型上放置屬性意味着屬性不僅是公共的,而且共享。這將成爲一個問題,當你的財產是一個可變類型,如Date

function MyObjectA() { } 
MyObjectA.prototype.date = new Date(2011, 10, 18); 
var obj1 = new MyObjectA(); 
var obj2 = new MyObjectA(); 
obj1.date.setDate(24); 
console.log(obj2.date); // Thanksgiving, not today 

參見Using "prototype" for variables

+0

謝謝;但不是它只是共享的初始值。在創建對象的新實例時,原型上的所有屬性都將被克隆;所以當我在一個實例中設置來自原型的屬性時,它不會影響其他實例,除非我設置了實際的原型對象。 – Peter

+0

@彼得 - 試試看。在您的瀏覽器中點擊F12並將我的代碼粘貼到JavaScript控制檯中。你會看到這些屬性確實是共享的。這是使用'prototype'的關鍵。如果所有東西都被克隆了,那麼與定義構造函數中的所有東西沒有任何區別。 – gilly3

+0

謝謝,我陷入了困境。我們只是誤解對方。初始值/參考值是共享的。當我說克隆時,我的意思是淺拷貝,它是一個新變量,但它仍然指向最初在屬性第一次添加到原型時創建的同一個「Date」對象。我的觀點是,對實例的後續設置不會影響其他實體。 – Peter

1

您可以將它們添加到contrustor爲VAR的而不是做this.something使 「私人」 瓦爾;像這樣:

function MyObject() 
{ 
    this.readableVar = "yes this is readable"; 
    var notReadable = "nope, not readable"; 
}; 

var ob = new MyObject(); 
document.body.innerHTML = ob.readableVar + "<br />" + ob.notReadable; 

這些不會被共享,因此是特定於您使用new創建的實例。

使用原型繼承時要記住的一件事是,每次訪問不在實例內部但在原型內部的變量時,在鏈的每個步驟中都會執行查找操作,直到找到匹配或在未定義鏈的頂部返回。 重複完成後,這可能會變成開銷。

希望它有助於PM5544。

+0

感謝您的快速響應。不過,我確實希望採用原型方法。我只想知道我是否應該將所有*屬性放在原型上,或者只有那些旨在公開的屬性。使用原型時更多的最佳實踐問題。 – Peter

+0

這些概念可以一起使用,例如,您可以創建一個具有原型的構造函數,其中包含所有共享公共資源和實例中的私有資源。 但試圖回答你的問題: 你放置你的變量的地方都依賴於數據模型,所以它總是一個var訪問性,易用性,可維護性和性能的問題。 所以我想每個情況都不一樣,需要一種不同的方法。 也許有些例子可以說明一些... – PM5544

+0

謝謝。我知道解決方案之間的關係。雖然它不是那麼有用,因爲原型上的方法將無法訪問private * closed over *實例變量。他們將是沒有特權的公共方法。我真的很喜歡你所建議的解決方案。我們試圖避免的內存開銷很小,這就是爲什麼我們要使用所有原型。說實話,我不確定這是否值得,因爲我們可以使用更多的方法來根據需要分割範圍。不過謝謝。 – Peter

1

我喜歡下面的模式:

function Rectangle(x,y) { 
    var _x = x, 
     _y = y; 
    this.area = function() { 
    return _x * _y; 
    } 
} 

_x和_y將是私人和麪積()將被公開。

+0

謝謝,我也很喜歡!雖然我在使用原型時詢問最佳實踐。我們希望使用原型儘可能減少內存。 – Peter

+0

你的例子並不相同。原型屬性的所有值將被所有實例共享(考慮一個類的靜態值)。在第一種情況下,myInternalProp_是實例的屬性(每個實例都有自己的值),在第二種情況下將被共享。 – 12000

+0

是的,這是事實。在這種情況下,構造函數不會更改初始值,但在更復雜的示例中,構造函數會設置新的* instance *特定值。我的問題更多的是一致性/最佳實踐的東西;基本上,爲什麼只在原型上設置一些,爲什麼不讓引擎知道所有的事情,因爲無論如何它們都是公開的。如果需要的話,我仍然可以在構造函數中設置實例值。 – Peter

相關問題