如下是幾種js中實現繼承的方式方法,它們也是各自有各自的優缺點,選擇哪種根據本身的應用而定,最適合本身的纔是最好的.javascript
function SuperType(){ this.name = 'yahualingfeng'; } SuperType.prototype.friends = ['David','Bob','Lucy']; SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(){ this.age = 30; } SubType.protoType = new SuperType();//經過原型對象繼承SuperType var subType1 = new SubType(); var subType2 = new SubType(); subType1.friends.push('Jake'); console.log(subType1.friends); // ['David','Bob','Lucy','Jake'] console.log(subType2.friends); // ['David','Bob','Lucy','Jake']
缺點:java
借用構造函數繼承是將超類(SuperType
)全部的屬性和方法都寫在構造函數中,最後在函數(SubType
)體內經過call
方法調用超類.函數
function SuperType(){ this.name = 'yuhualingfeng'; this.friends =['David','Bob','Lucy']; this.sayName = function(){ alert(this.name); } } function SubType(){ SuperType.call(this); } var subType = new SubType(); subType.sayName();
缺點:方法的定義都存在構造函數中,致使函數沒法被複用.this
組合繼承是原型鏈繼承和構造函數繼承的結合體,結合了兩者的優勢,即實現了函數的複用,也不會致使引用類型值在多個實例中共享.prototype
function SuperType(){ this.name='yuhualingfeng'; this.friends=['David','Bob','Lucy']; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(){ SuperType.call(this); } SubType.prototype = new SuperType(); var subType = new SubType();
缺點:code
SuperType
自身的屬性(name
,friends
)被重複定義,即出如今SubType
的構造函數中,也出如今SubType
的原型對象中.原型繼承是繼承自一個對象而不是引用類型.對象
function object(obj){ function F(){} F.prototype = obj; return new F(); }
這裏的object方法接收obj對象,並將對象賦值給一個空函數的原型,並返回空函數的實例.繼承
var person = { name:'yuhualingfeng', friends:['David','Bob','Lucy'] }; var anotherPerson = object(person); anotherPerson.name = 'Jake'; anotherPerson.friends.push('Marry'); console.log(anotherPerson.friends); //['David','Bob','Lucy','Marry'] console.log(person.friends); //['David','Bob','Lucy','Marry']
若是不想建立構造函數,只想讓一個對象和另外一個對象保持一致的狀況下,原型繼承是徹底能夠勝任的,不過有一點要注意的是,假如繼承的屬性值爲引用類型時,仍是會相互影響的.ip
寄生繼承是基於原型繼承的基礎上擴展本身的屬性和方法.ci
function createrAnother(obj){ var clone = object(obj); clone.sayHi=function(){ alert('Hi!'); } return clone; } var person = { name:'yuhualingfeng' }; var anotherPerson = createAnother(person); anohterPerson.sayHi(); // Hi
寄生繼承也是和原型繼承同樣也是繼承對象,併產出對象.
顧名思義,寄生組合繼承是集寄生繼承和組合繼承的結合體,它結合了兩者的優勢.
//繼承Supertype的原型對象 function inheritProtoType(SuperType,SubType){ var prototype = object(SuperType.prototype); prototype.constructor = SubType; SubType.prototype = prototype; } function SuperType(){ this.name = 'yuhualingfeng'; this.friends = ['David','Bob','Lucy']; } function SubType(){ ////繼承Supertype的構造函數屬性 SuperType.call(this); this.age = 30; } inheritProtoType(SuperType,SubType); var subType = new SubType();
寄生組合繼承是前面幾種繼承思想碰撞在一塊兒的產物,是執行效率最高也是應用面最廣的.
原型鏈繼承
是經過爲原型對象賦值,不足之處爲引用類型值會被多個實例共享,構造函數繼承
解決了原型鏈繼承
的問題,同時也暴露出新的問題是函數的複用沒法實現,而後咱們結合兩者的優缺點,構造出了組合繼承
,組合繼承
基本上知足了咱們想要的繼承結果.
考慮到執行的效率,咱們構思出了寄生繼承
(基於原型繼承),並將寄生繼承
和組合繼承
結合,最終得出了繼承的最優解決方案'寄生組合繼承
.