js继承
es5继承:
- 借用构造函数
function A () { this.name = 'zsp' } A.prototype.sayHello = funtion() { console.log(`hi ${ this.name }`) } function B() { A.call(this) }
缺点:无法继承父类原型上的属性。为了避免每次创建实例时重复创建函数实例,函数属性一般都定义在原型上。
- 组合继承
function A () { this.name = 'zsp' } A.prototype.sayHello = funtion() { console.log(`hi ${ this.name }`) } function B() { A.call(this) } B.prototype = new A() B.prototype.constructor = B
缺点:原型上继承了不必要的属性。因为B的原型为A的实例,A的实例中一些来自A的构造函数的属性,这些属性已经在A.call(this)中继承得到。
- 寄生式组合继承
function A () { this.name = 'zsp' } A.prototype.sayHello = funtion() { console.log(`hi ${ this.name }`) }
function B() {}
const p = object.create(A.prototype)
p.constructor = B
B.prototype = p寄生式组合继承使用object.create方法,以父类的原型作为参数生成一个新的prototype,作为子类的原型。
es6继承:
class B extends A { constructor(x, y, color) { super(x, y); // 调用父类的constructor(x, y) this.color = color; } toString() { return this.color + ' ' + super.toString(); // 调用父类的toString() } }
constructor
方法和toString
方法之中,都出现了super
关键字,它在这里表示父类的构造函数,用来新建父类的this
对象。
子类必须在constructor
方法中调用super
方法,否则新建实例时会报错。这是因为子类没有自己的this
对象,而是继承父类的this
对象,然后对其进行加工。如果不调用super
方法,子类就得不到this
对象。