本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、原型链继承
1. 核心原理:构造函数的实例指向继承对象的原型链。
- 核心代码
function Animal() {}
function Dog() {}
Dog.prototype = new Animal()
2. 完整继承示例
function Animal() {
this.colors = ['black', 'white']
}
Animal.prototype.getColor = function() {
return this.colors
}
function Dog() {}
Dog.prototype = new Animal()
let dog1 = new Dog()
dog1.colors.push('brown')
let dog2 = new Dog()
console.log(dog2.colors) // ['black', 'white', 'brown']
3. 缺点
- 原型中包含的引用类型属性将被所有实例共享
- 子类在实例化的时候不能给父类构造函数传参
二、构造函数继承
1. 核心代码及实现原理
子类初始化时调用父类的构造函数。
function Animal2(name) {}
function Dog2(name) {
Animal2.call(this, name)
}
Dog2.prototype = new Animal2()
2. 完整继承示例
function Anima3(name) {
this.name = name
this.getName = function() {
return this.name
}
}
function Dog3(name) {
Animal3.call(this, name)
}
Dog3.prototype = new Animal3()
3. 缺点
方法必须定义在构造函数中,所以会导致每次创建子类实例都会创建一遍方法
三、组合继承
- 原型链实现对原属性的属性和方法的继承
- 通过构造函数实现其对实例的继承
- 这样既可以把方法定义在原型上以实现重用,又可以让每个实例都有自己的属性。
1.核心代码
function Animal4(name) {}
function Dog4(name) {
Animal4.call(this, name)
}
Dog4.prototype = new Animal4()
Dog4.prototype.constructor = Dog4
2. 完整示例
function Animal(name) {
this.name = name
this.colors = ['black', 'white']
}
Animal.prototype.getName = function() {
return this.name
}
function Dog(name, age) {
Animal.call(this, name)
this.age = age
}
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
let dog1 = new Dog('奶昔', 2)
dog1.colors.push('brown')
let dog2 = new Dog('哈赤', 1)
console.log(dog2)
// { name: "哈赤", colors: ["black", "white"], age: 1 }
3. 缺点
调用了两次父类构造函数。
四、 寄生式组合继承
function Animal2(name) {}
function Dog2(name) {
Animal2.call(this, name)
}
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog
观察以上代码,再对比下组合继承,代码修改如下:
- Dog.prototype = new Animal()
- Dog.prototype.constructor = Dog
+ Dog.prototype = Object.create(Animal.prototype)
+ Dog.prototype.constructor = Dog
简单的说,继承对象的原型链指向从父对象的实例变成了父对象的原型链对象。
五、 class继承
使用es6的class关键字继承,这个语法糖用起来应该是很香的,唯一需要注意的就是子类必须在constructor方法中调用super方法,否则新建实例时会报错。因为子类自己的this对象必须先通过父类的构造函数构造。
class Point {
}
class ColorPoint extends Point {
}
// 等同于
class ColorPoint extends Point {
constructor(...args) {
super(...args);
}
}
更多class
用法请参考阮一峰老师的ECMAScript 6 入门