首先要明确两点:
一、非办法属性每个子类实例须要独立
二、办法属性每个子类实例须要共享
为什么?
如果非办法属性为援用类型,且非办法属性共享,在一个实例中扭转,其余实例中就会做出扭转,这样每个实例就会相互影响,而办法属性个别是不须要进行扭转的,只是对办法调用。

1. 基于原型链的继承

每个函数都有个prototype属性,每个对象都有__proto__属性(在chrome中体现如此,prototype也是如此) 如图,属性的查找会从以后层级顺次向原型链上查找,直到查找到原型链的顶端null,具体可参考js proto

既然属性的查找是依照原型链向上查找的,且继承就是继承父类的属性跟办法,那么就能够利用这个个性,进行继承。

function SuperType() {  this.property = true;}SuperType.prototype.getSuperValue = function () {  return this.property;};function SubType() {  this.subproperty = false;}// 继承SuperTypeSubType.prototype = new SuperType();SubType.prototype.getSubValue = function () {  return this.subproperty;};let instance = new SubType();console.log(instance.getSuperValue()); // true 能够正确调用父类的办法,拿到父类的属性

原型尽管实现了继承,然而还是有毛病的
劣势:

1. 子类或者父类的属性为援用类型时,扭转一个实例的援用类型属性,其余实例的该援用类型属性也会产生扭转,这样其实例就会互相净化了。
function SuperType() {  this.colors = ["red", "blue", "green"];}function SubType() {} // 继承SuperTypeSubType.prototype = new SuperType();let instance1 = new SubType();instance1.colors.push("black");console.log(instance1.colors);// "red,blue,green,black";let instance2 = new SubType();console.log(instance2.colors);// "red,blue,green,black";

为什么非办法属性不写在prototype上?

因为prototype上的属性的共享的,在一个实例上改了该属性,其余实例的该属性也会被改掉。

为什么办法不写在构造函数外部?

办法写在子类外部:每次实例化构造函数,办法都是新的;办法只是用来调用,不须要批改,所以实例共享就行了。
办法写在父类外部:不同的子类继承父类都须要实例化父类;办法只是用来调用,不须要做批改,所以实例共享就行了,包含子类实例。如果子类须要批改父类办法,间接在子类中定义雷同办法名,进行笼罩就行了。

2. 子类在实例化时不能给父类的构造函数传参,因为父类的实例化是在后面,而不是结构函数调用的时候。