引言
继承的本质是对原型链的操作,具体来说有三种方式:
1.通过构造函数实现
2.通过原型链实现
3.前面两种方式的组合实现
代码示例
function Rectangle(length,width){
this.l = length;
this.w = width;
}
Rectangle.prototype.getArea = function(){
return this.l = this.w
}
function Square(length){
Rectangle.call(this.length,length)
}
Square.prototype = Object.create(Rectangle.prototype,{
constructor:{value:Square}
})
var square = new Square(3);
console.log(square.getArea());
console.log(square instanceof Square);
console.log(square instanceof Rectangle)
实现效果

继承的实现.png
代码讲解
为何第一个console.log是undefined但第二个console.log是true
这个主要是借用call 来改变this的指向,通过 call 调用 Rectangle,此时 Rectangle中的 this 是指 Square。有个缺点,从打印结果看出 Square并没有getArea方法,所以这种只能继承父类的实例属性和方法,不能继承原型属性/方法。
第三个console.log为何是true
通常 prototype里面有一个 constructor, 而我们此时子类的 prototype 指向是 父类的 prototye ,而父类prototype里面的contructor当然是父类自己的。使用Object.create(),它的作用是将对象继承到proto属性上。这样Square就继承了Rectangle的prototype 。之所以要在Object.create()中重新写一个constructor,是因为不写的话,constructor是指向Rectangle的,这样square instanceof Rectangle的时候,会顺着原型链找到Rectangle的constructor,所以需要新建一个constructor赋值给Square