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实例化的时候在执行一次
this.age = age;
}
Sub.prototype = new Super('父类'); // 父类执行了一次
// 思考为什么这里不直接 Sub.prototype = Super.prototype ???
Sub.prototype.constructor = Sub;
// 修复Sub原型constructor的指向,
var inst1 = new Sub('子类');
除了Super会执行2次损耗一点点性能,几乎完美的继承
Sub.prototype = Super.prototype 可以实现功能,去掉一层继承链,但是子类和父类共用了原型,这样子类在原型增加属性和方法,父类也会受影响,而且还修改了原型的constructor指向,所以不能这么干。
知道了努力的方向那么我们可以把
Sub.prototype = new Super('父类');
修改为Sub.prototype = Object.create(Super.prototype)
var a = Object.create(b) ; a.__proto__ === b //b需要是一个对象
就是说Sub.prototype不能直接等于Super.prototype,要引入一个中间商,a就是一个中间商,这个中间商不是以new Super创建出来的,这样Super.prototype上添加的属性inst1可以直接使用,而Sub.prototype === a ;在a上添加属性又不会影响到Super;完美的解决方案。