ES5和ES6都可以实现继承,但是两者实现的方式是不一样的,下面分别用代码实现一下,并说明它们的区别
ES5实现继承的方式有多种,但是每种的含义都不一样
一、原型链实现继承
1 | function Parent(name){ |
实现原理:子类的原型对象指向父类的实例来实现继承,也就是重写子类的原型,但这种方式无法实现多继承
二、call/apply方法改变函数上下文实现继承
1 | function Parent(name){ |
实现原理:改变函数内部的函数上下文this,使它指向传入函数的具体对象,其实就是将父类的this指向子类。但这种方式不能继承父类的原型链
三、结合以上两种方式,共同实现继承
1 | function Parent(){ |
实现原理:这种方式是结合了以上两种的原理共同实现的,既可以实现多继承,也可以继承父类的原型链
ES6实现继承
ES6实现继承的方式很简单,其定义了extends
关键字,可以方便实现继承
1 | class Parent { |
两者的区别
两者实现继承的方式和内部的原理是不一样的,引用阮大大的话:ES5实现继承是先创造子类的实例对象this
,然后再将父类的方法添加到this
上(Parent.call(this)
)。ES6的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this
上,所以必须调用super
方法,然后子类的构造函数修改this
。
这里有几点需要注意:
1、如果子类继承父类,但内部不写构造函数的话,构造函数是会被默认添加的,即:
1 | class ColorPoint extends Point { |
2、如果在子类中写了构造函数,则必须先调用super
之后,才可以使用this
,否则会报错。这是因为子类实例的构建,是基于父类实例,只有super
方法才能调用到父类的实例,即:
1 | class Point { |
3、父类的静态方法,也会被子类继承,即:
1 | class A { |