2.借用構造函數
為解決原型中包含引用類型值所帶來的問題, 我們使用一種叫做 借用構造函數(constructor stealing)的技術(又叫偽造對象或經典繼承)。
這種技術的基本思想:在子類構造函數內部調用超類型構造函數。
通過使用apply()和call()方法可以在新創建的子類對象上執行構造函數。
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ //繼承了 SuperType SuperType.apply(this); } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //red,blue,green,black var instance2 = new SubType(); alert(instance2.colors); //red,blue,green
在上述例子中,實際上是在新創建的SubType實例(instance1 instance2)的環境下調用了SuperType的構造函數。這樣一來,就會在新SubType對象上執行SuperType()函數中定義的所有對象初始化代碼。 所以Subtype的每個實例就都會具有自己的colors屬性的副本了。
傳遞參數
對於原型鏈來講,借用構造函數有一個很大的優勢,即可以在子類型構造函數中想超類型構造函數傳遞參數。
function SuperType(name){ this.name = name; } function SubType(){ SuperType.call(this, "Bob"); this.age = 18; } var instance1 = new SubType(); alert(instance1.age); //18 alert(instance1.name); //Bob
借用構造函數的問題:
方法都在構造函數中定義,因此函數復用就無從談起了。而且,在超類型的原型中定義的方法,對子類型而言也是不可見的。
3. 組合繼承
組合繼承(combination inheritance), 有時候也叫作偽經典繼承, 指的是將原型鏈和借用構造函數的技術組合到一起。從而發揮二者之長的一種繼承模式。
使用原型鏈實現對原型屬性和方法的繼承;
通過借用構造函數來實現對實例屬性的繼承。
這樣,既通過在原型上定義方法實現了函數的復用,又能保證每個實例都有他自己的屬性。
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); } function SubType(name, age){ //繼承屬性 SuperType.call(this, name); this.age = age; } //繼承方法 SubType.prototype = new SuperType(); SubType.prototype.sayAge = function(){ alert(this.age); } var instance1 = new SubType("Bob", 22); instance1.colors.push("black"); alert(instance1.colors); //red,blue,green,black instance1.sayName(); //Bob instance1.sayAge(); //22 var instance2 = new SubType("Alice", 21); alert(instance2.colors); //red,blue,green instance2.sayName(); //Alice instance2.sayAge(); //21
在這個例子中, SuperType構造函數定義了兩個屬性: name和colors。 SuperType的原型定義了一個方法sayName()。
SubType構造函數在調用SuperType構造函數時傳入了name參數,定義了他自己的屬性age。然後將SuperType的實例賦值給SubType的原型。在該原型上定義了方法sayAge()。
這樣一來,就可以讓兩個不同的SubType實例既分別擁有自己的屬性 - 包括colors屬性,又可以使用相同的方法。
以上這篇淺談JS繼承_借用構造函數 & 組合式繼承就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持。