上文提到我們不會單獨使用基於函數偽造的方式實現繼承,而是會使用基於原型鍊和函數偽裝組合的方式實現繼承。這種繼承方式也叫偽經典繼承,它的想法是使用原型鏈實作原型屬性和方法的繼承,而藉由借用建構函式來實現實例屬性的繼承。這樣,既透過在原型上定義方法實現了函數的複用,又能夠保證每個實例都有它自己的屬性。
來看下面的例子,我們先列出基於原型鍊和函數偽裝組合的方式實作繼承完整的程式碼,然後再對程式碼中的每一步做記憶體模型分析。
// 第一部分 function Parent(name){ this.color = ["red","blue"]; this.name = name; } Parent.prototype.talk = function(){ alert(this.name+"["+this.color+"]"); } // 第二部分 function Child(name,age){ //函数伪造继承 Parent.call(this,name); this.age = age; } // 原型链继承 Child.prototype = new Parent(); Child.prototype.say = function(){ alert(this.name+","+this.color); } //第三部分 var c1 = new Child("Leon",22); c1.color.push("green"); c1.say(); // 输出:Leon[red,blue,green] var c2 = new Child("Ada",25); c2.say(); // 输出:Ada[red,blue]
我們先來看程式碼中的第一部分,在這段程式碼中,我們建立了父類Parent,並為它增加了2個屬性。然後在Parent的原型中加入一個方法talk()。此時的記憶體模型如下圖所示:
接下來在程式碼的第二部分,我們建立了子類別Child,在子類別Child內部使用函數偽造的方式繼承父類別的屬性。然後透過原型鏈繼承的方式使子類別的原型指向父類別對象,並在新的子類別原型上添加了一個say()方法。此時的記憶體模型如下圖所示:
最後,在第三部分程式碼中,我們分別建立了兩個子類別物件c1和c2。然後為c1物件的color屬性新增一個新的顏色,並呼叫c1的say()方法,對於c2同樣也呼叫它的say()方法。此時的記憶體模型如下圖所示:
我們可以看到,為物件的引用型別屬性設定值是在它自己的空間中完成的,這樣每一個物件都有它自己獨立的屬性,互不干擾。
以上就是基於原型鍊和函數偽裝組合的方式實現繼承的完整程式碼和記憶體模型分析,也是我們在JavaScript中最常用的一種實現繼承的方式,更多相關內容請關注PHP中文網(www. php.cn)!