我們先來看看直覺使用 new 這個函式建構關鍵字建立物件時,可能寫出的程式碼
[javascript] function person() { this.firstName=“camel”; this.lastName=“chang”; this.fullName=function(){ console.log(this.firstName+” “+this.lastName); }; } var a=new person(); console.log(a); // person{firstName: “camel”, lastName: “chang”, fullName: function()} [/javascript]
這種寫法看起來蠻直覺,但當我們有多個 person 物件時,其中的 fullName() 其實是相同的方法,他們應該可以共用此方法。
但這種寫法會導致每個 person 物件都擁有一個 fullName 方法,佔有較多記憶體。
若使用以下函式原型(prototype)的方法的話,所有 person 物件都繼承同一個函式 constructor 的方法。
但其實當我們今天使用 new 這個函式建構關鍵字建立物件時,物件會繼承原有函式的原型(prototype)方法
比如說:
[javascript] function person() { this.firstName=“camel”; this.lastName=“chang”; } console.log(person.prototype); // {} person.prototype.fullName=function(){ console.log(this.firstName+” “+this.lastName); }; var a=new person(); console.log(a); // {firstName: “camel”, lastName: “chang”} a.fullName(); // camel chang [/javascript]
從上面這段程式碼,我們可以觀察到以下幾點
- 每個函式預設會有 prototype 屬性,預設為空物件{}。
- 當我們使用 new 函式建構物件時,物件會繼承原函式中的 prototype 屬性,至 __proto__.constructor 中。
- 因此當我們嘗試使用物件呼叫此函式原有方法時,將會是繼承自函式原型(prototype)的方法。
PS. 注意,函式的 prototype 並不代表函式原型,也就是並不能以 prototype 存取 proto。
再來可能有人會疑問,如果要更改物件的原型(prototype)方法,只能使用一行一行指定 prototype 之中的方法嗎?
其實有一個 javascript 建立物件的方法 Object.create(),這個方法提供傳入一個物件參數。
它將幫助你根據此物件建立相關的原型(prototype)方法,直接看程式碼吧~
[javascript] var person={ “firstName”: “camel”, “lastName”: “chang”, “getFullName”: function(){ console.log(this.firstName+” “+this.lastName); } }; var camel=Object.create(person); console.log(camel); // Object{},所有的屬性與方法都設定至原型(prototype)方法了 camel.getFullName(); // camel chang [/javascript]
這樣我們就可以根據某個通用物件建立基本的物件,再針對各物件去宣告獨有的屬性與方法! 參考資料:
https://pjchender.blogspot.tw/2016/06/javascriptfunction-constructorprototype.html
https://pjchender.blogspot.tw/2016/06/javascriptprototypal-inheritance.html