淺談JS中的構造函數、原型對象(prototype)、實例中的屬性/方法之間的關系


原文鏈接: https://segmentfault.com/a/1190000016951069

構造函數:函數中的一種,通過關鍵字new可以創建其實例。為了便於區分,通常首字母大寫;
原型對象:一種特殊的對象,構造函數創建時自動生成;與構造函數形成一一對應,如同人和影子般的關系;
實例:通過構造函數實例出來的對象;


  在定義構造函數時,在其內部(“{“和”}”)進行定義屬性和方法。當我們通過關鍵字new,對構造函數進行實例化的時候。實例會對構造函數的這些屬性進行拷貝出一份副本,然后將其歸屬為當前實例。不同實例間的屬性和方法是完全獨立的,如下例子:

function Person(name,age){
    this.name = name;
    this.age = age;
    this.sayName = function(){
           alert(this.name);
    };
}
 
var HL = new Person("hailing",18);
var JJ = new Person("jiajia",20);
 
HL.sayName(); // hailing
JJ.sayName(); // jiajia
 
HL.name = "HAILING";
 
HL.sayName(); // HAILING
JJ.sayName(); // jiajia

  我們通過創建了new對Person進行實例化兩個對象“HL”、“JJ”,當我們在修改“HL”的名字時,“JJ”的名字不會隨之而改變。

  程序執行時,會自動生成一個原型對象(prototype)與之相關聯。同時給該構造函數自動添加一個屬性:prototype,該屬性為指針,指向原型對象。同時,也給該原型對象添加一個屬性:constructor,該屬性也為指針,指向與其對應的構造函數。此時,原型對象中只會包含些默認的方法和屬性。

  實例化完成后,所有實例均會與原型對象形成多對一的隱性關聯關系。所有實例會共享原型對象的屬性和方法,當然也包括constructor。當原型對象被添加一個屬性或者方法后,均會被所有實例共享,即可以通過任意一個實例進行訪問。如果原型對象的屬性或方法與實例的屬性或方法名稱一致,則實例自身的屬性或方法優先級高於原型對象上的:

//添加公共的屬性和方法
Person.prototype.sex = "girl";
Person.prototype.saySex = function (){
   alert(this.sex);
};
alert(HL.saySex === JJ.saySex); // true
alert(HL.saySex === Person.prototype.saySex); // true
 
Person.prototype.stature = 165;
alert(HL.stature); // 165
alert(JJ.stature); // 165
 
//為實例對象修改或者添加私有屬性。
HL.stature = 160;
alert(HL.stature); // 160
alert(JJ.stature); // 165
 
//刪除實例對象的私有屬性。
delete HL.stature;
Person.prototype.stature = 170;
alert(HL.stature); // 170
alert(JJ.stature); // 170

  例子中,給原型對象增加了sex屬性和saySex方法,此時通過實例對象“HL”和“JJ”訪問並且進行比較,同時也和原型對象自身的saySex進行比較,結果為ture;而后又給原型對象增加了stature屬性,此時“HL”和“JJ”中均無此屬性,故訪問了原型對象中的stature屬性。當我們單獨給“HL”增加了stature屬性后,“HL”不在訪問原型對象,而是訪問“HL”自身的該屬性。當我們通過關鍵字“delete”刪除“HL”自身的屬性后,再次訪問時,又回重新訪問原型對象上的屬性。


總結: 構造函數中的屬性和方法僅為聲明和定義,一旦實例化工作完成后。實例對象自身的屬性和方法與構造函數將不在存在關聯關系。原型對象與實例對象形成“備胎”關系,當通過對象訪問屬性或方法時,程序會優先搜索對象本身的屬性或方法,不存在才會訪問原型對象的方法或者屬性。

  因此,當多個實例需要使用同一個屬性或方法時,我們應該將該方法放於原型對象上,從而避免相同屬性或方法多次獨立存在於多個對象導致內存浪費。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM