es6以前的做法:javascript
方法一:原型鏈 (與java的類多層繼承思想相似,python能夠多重繼承,MixIn是經常使用的設計思想)
缺點: 當父級的屬性有引用類型的時候,任意一個實例修改了這個屬性,其餘實例都會受影響java
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function subType() { this.property = false; } //繼承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.property; } var instance = new SubType(); console.log(instance.getSuperValue());//true
方法二:借用構造函數
缺點:建立多個實例 , 父類的方法會被建立屢次。instance1.colors == intance2.colors // false python
function SuperType(){ this.colors = ["red","blue","green"]; } function SubType(){ SuperType.call(this);//繼承了SuperType } var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors);//"red","blue","green","black" var instance2 = new SubType(); console.log(instance2.colors);//"red","blue","green"
方法三:組合繼承
缺點: 父類的構造器被調用了兩次es6
function SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { console.log(this.name); } function SubType(name, age) { SuperType.call(this,name);//繼承屬性 this.age = age; } //繼承方法 SubType.prototype = new SuperType(); Subtype.prototype.constructor = Subtype; Subtype.prototype.sayAge = function() { console.log(this.age); } var instance1 = new SubType("EvanChen",18); instance1.colors.push("black"); consol.log(instance1.colors);//"red","blue","green","black" instance1.sayName();//"EvanChen" instance1.sayAge();//18 var instance2 = new SubType("EvanChen666",20); console.log(instance2.colors);//"red","blue","green" instance2.sayName();//"EvanChen666" instance2.sayAge();//20
方法四:原型式繼承
用一個函數包裝一個對象,而後返回這個函數的調用,這個函數就變成了個能夠隨意增添屬性的實例或對象,結果是將子對象的__proto__
指向父對象
缺點:共享引用類型 (相互影響)函數
function object(o) { function F(){} F.prototype = o; return new F(); } //示例 var person = { name:"EvanChen", friends:["Shelby","Court","Van"]; }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
方法五:寄生組合式繼承
改進組合繼承,利用寄生式繼承的思想繼承原型this
function inheritPrototype(subType, superType){ var protoType = Object.create(superType.prototype); //建立對象 protoType.constructor = subType; //加強對象 subType.prototype = protoType; //指定對象 } 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; } inheritPrototype(SubType, SuperType) SubType.prototype.sayAge = function(){ alert(this.age); } var instance = new SubType("Bob", 18); instance.sayName(); instance.sayAge();
==== Es6 class繼承spa
- 繼承中,若是實例化子類輸出一個方法,先看子類有沒有這個方法,若是有就先執行子類的
- 繼承中,若是子類裏面沒有,就去查找父類有沒有這個方法,若是有,就執行父類的這個方法(就近原則)
- 若是子類想要繼承父類的方法,同時在本身內部擴展本身的方法,利用super 調用父類的構造函數,super 必須在子類this以前調用
// 父類有加法方法 class Father{ constructor(x,y) { this.x = x ; this.y = y ; } sum() { console.log(this.x + this.y); } } // 子類繼承父類加法的方法, 同時 擴展減法方法 class Son extends Father { constructor (x,y){ // 利用super調用父類的構造函數 // super必須在子類this以前調用 super(x,y); this.x = x; this.y = y; } subtract(){ console.log(this.x - this.y); } } var son = new Son(20,10); son.subtract();//10 son.sum(); //30