2011-09-20 86 views
4

這兩個對象的構造有什麼區別 - 除了成員變量的隱私?Javascript對象構造:有什麼區別?

function A() { this.a = 99; } 
A.prototype.setA = function(newVal) { this.a = newVal; } 
A.prototype.getA = function({ return this.a; } 

這:

function A() { 
    var a = 99; 
    return { 
     setA: function(newVal) { a=newVal; } 
     getA: function() { return a; } 
    } 
} 

我不感興趣的成員變量這麼多的功能被定義方式的隱私。

我是否認爲在第二個版本中,通過新的A()創建的所有對象都會獲得已定義函數的副本,在第一個版本中,所有對已定義函數的調用將轉到唯一原型對象(對於A對象)。這是正確的嗎?

如果是這樣,版本2有任何性能成本?

另外,一種方式是否優於另一種 - 或者還有更好的方法嗎?

非常感謝

+0

安裝者和吸氣者是一個可怕的想法。停止將Java代碼移植到JavaScript。 – Raynos

+0

@Raynos,不太可怕,不會被納入ES5。 – davin

+0

@達文這是不同的。這些是本地的getter/setter(他們仍然是邪惡的)。像'setA'和'getA'這樣的模擬器是非常愚蠢的。 Native Native getter/setters應該只用於做真正聰明的事情,而不是每天都在使用代碼 – Raynos

回答

6

我是正確的思維,在第二版中的所有對象通過new A()創建 將獲得的定義的函數,其中作爲 第一個版本調用所有副本定義的函數將會轉到一個 並且只有原型對象(對於A對象)。這是正確的嗎?

如果是這樣就第2版有任何性能成本?與組A和每個對象的木屐

更多的內存使用量的

而且,是一種方式優於另一種 - 或者是有沒有更好的辦法 一遍嗎?

既然你不關心封裝,使用原型

1

內變量一旁的隱私,這些行爲應該相似,但你是正確的,第二個版本將使用更多的內存比第一。這通常是微不足道的,除非你使用大量的對象,但使用原型方法只有一個getA和setA函數,而第二種方法每個都有自己的這些方法的函數。

1

你在兩個帳戶上都是正確的。

因此,性能差異將是內存消耗 - 第二種方式會消耗更多的每個對象。另外,在第二個版本中,每個對象的創建/實例可能會稍微延長一點,因爲你必須創建那些耗費內存的函數,儘管這個可以忽略不計(在這個玩具的情況下),甚至可能被實現相關的因素所抵消。

我會建議原型方法,因爲這些原因,它略微好一些。關於能見度,甚至可以用ES5以原型的方式僞造實施。

2

第一種方法將這些函數定義爲A.prototype對象的屬性,這意味着對於A的所有實例,這些函數在一個位置中定義。

第二種方法直接在實例對象上定義函數(作爲屬性),這意味着您將爲每個創建的實例(=更高的內存消耗)提供一組新的函數。

第一種方法的優點是,您可以根據需要影子繼承方法

A.prototype.foo = function() { ... }; 

var a = new A; 
a.foo(); // inherited 
a.foo = function() { ... }; 
a.foo(); // shadowed 
delete a.foo; 
a.foo(); // back to inherited 

在使用第二種方法時,不能這樣做。

第二種方法的優點是功能捕捉構造的情況下,這樣你就可以在其中,然後可以通過你的函數用來構造私有變量和函數。

這不能與原型定義的函數來完成。


所以我的建議是: 如果您需要私有變量或函數,使用第二種方法。否則,使用原型。

+0

+1用於很好地總結差異並推薦何時使用它們。 – jfriend00

相關問題