2016-09-19 226 views
0

拿這個例子:javascript原型上的屬性與對象有什麼區別?

var personPrototype = { 
firstName: '', 
lastName: '', 

getFullname: function() { 
    return this.firstName + ' : ' + this.lastName; 
    } 
} 

Person = { 

}; 

function newPerson(firstName, lastName) { 
    var Person = function(firstName, lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 
    Person.prototype = personPrototype; 
    return new Person(firstName, lastName); 
} 

var p1 = newPerson('someone', 'else'); 
var p2 = newPerson('john', 'doe'); 
console.log(p1.getFullname()); 
console.log(p2.getFullname()); 

從personPrototype移動名字和姓氏的人得到相同的結果。這是否意味着兩者之間沒有區別,還是我忽略了某些東西?

+0

您不應該每次在'newPerson'工廠函數中重新創建'Person'構造函數。如果您想使用工廠函數,請改用[Object.create'](http://stackoverflow.com/a/39546963/1048572)。 – Bergi

回答

1

直接放置在對象上的屬性與放置在對象原型上的屬性之間的區別非常重要。原型由對象的所有實例共享。在對象中定義的屬性(如在構造函數中)將在每個實例上定義。

我懷疑你在定義你的Person對象時感到困惑。全局範圍內的Person正被newPerson中的構造函數覆蓋,並且從不使用。除非您有特定的理由在對象的所有實例之間共享一個值,否則不需要在構造函數/方法函數外定義屬性。

至於爲什麼定義原型中的屬性沒有什麼區別:它是the prototype chain。當你在personPrototype中定義firstName等,然後在構造函數中也會覆蓋它。因此,致電getFullName回落到personPrototype,然後在Person的當前實例上查找lastName,從而獲得當您撥打new Person(firstName, lastName)時傳遞的值。

+0

「更多面向對象」是什麼意思?短暫聊天? – Bergi

+0

我的意思是一種更正式面向對象的語言,就像Java一樣,你必須在構造函數方法之外詳細說明類結構。但它只是推測性的,並沒有真正添加任何答案,所以我已經刪除它。 – user2005218

+0

謝謝,實際上對我來說(仍然有點)困惑的部分是我會懷疑原型中的屬性被所有實例共享。類似於C++中的靜態屬性(它們實際上是類級別的屬性)。那麼,我希望這些屬性可以被不同的實例共享,從而被覆蓋,使得p1和p2都是John Doe。但事實並非如此。 – dexter

相關問題