javascript实现继承的几种方式
2016/03/21
继承可以使得子类具备父类的各种方法和属性
原型链继承
最常见的继承方式,继承成员定义在prototype
上
const Parent = function () {
this.value = "value from parent"
}
const Child = function () {}
Child.prototype = new Parent()
const childInstance = new Child()
console.log(childInstance.value) // "value from parent"
缺点是
- 引用类型的属性被所有实例共享,修改时影响所有实例
- 创建子类时不能向父类传递参数
const Parent = function () { this.values = [1, 2, 3] } const Child = function () {} Child.prototype = new Parent() const instance1 = new Child() const instance2 = new Child() console.log(instance1.values) // [1, 2, 3] console.log(instance2.values) // [1, 2, 3] instance1.values.push(4) console.log(instance2.values) // [1, 2, 3,4 ] console.log((new Child()).values) // [1, 2, 3, 4]
构造函数继承
const Parent = function (a, b) {
this.value = "value from parent"
this.a = a
this.b = b
}
const Child = function () {
Parent.call(this, ...arguments)
}
const instance = new Child(1, 2)
console.log(instance)
构造函数继承的优点是引用类型的属性不会被共享并且可以传参,缺点是只继承父类,不继承原型
const Parent = function () {
this.values = [1, 2, 3]
this.getValue1 = function () {
return this.values
}
}
Parent.prototype.getValue2 = function () {
return this.values
}
const Child = function () {
Parent.call(this)
}
const instance = new Child()
console.log(instance.getValue1()) // [1, 2, 3]
console.log(instance.getValue2()) // 报错
es6继承-extends
Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {}
}
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y);
this.color = color; // 正确
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}