es6的繼承:
class Super{
constructor(name){
this.name=name;
}
getName(){
return this.name;
}
}
class Sub extends Super{}
let inst1 = new Sub('inst1');
let inst2 = new Sub('inst2');
// inst1和inst2的name屬性不共享,getName方法是在原型鏈的上游,被共享
es6的繼承寫法簡潔方便,十分直觀。
es5的繼承:(只推薦組合繼承--最常用)
組合繼承
function Super(name){
this.name = name;
this.con = function(){
};
}
Super.prototype.getName = function(){}
function Sub(name, age){
Super.call(this, name); // 這里等Sub實(shí)例化的時(shí)候在執(zhí)行一次
this.age = age;
}
Sub.prototype = new Super('父類'); // 父類執(zhí)行了一次
// 思考為什么這里不直接 Sub.prototype = Super.prototype ???
Sub.prototype.constructor = Sub;
// 修復(fù)Sub原型constructor的指向,
var inst1 = new Sub('子類');
除了Super會(huì)執(zhí)行2次損耗一點(diǎn)點(diǎn)性能,幾乎完美的繼承
Sub.prototype = Super.prototype 可以實(shí)現(xiàn)功能,去掉一層繼承鏈,但是子類和父類共用了原型,這樣子類在原型增加屬性和方法,父類也會(huì)受影響,而且還修改了原型的constructor指向,所以不能這么干。
知道了努力的方向那么我們可以把
Sub.prototype = new Super('父類'); 修改為Sub.prototype = Object.create(Super.prototype)
var a = Object.create(b) ; a.__proto__ === b //b需要是一個(gè)對象
就是說Sub.prototype不能直接等于Super.prototype,要引入一個(gè)中間商,a就是一個(gè)中間商,這個(gè)中間商不是以new Super創(chuàng)建出來的,這樣Super.prototype上添加的屬性inst1可以直接使用,而Sub.prototype === a ;在a上添加屬性又不會(huì)影響到Super;完美的解決方案。