构造函数的继承方式及其优缺点
一,原型链继承
实现方式:将子类的prototype挂在父类的实例上
function Person() {
this.name = '小明';
this.eats = ['吃苹果'];
this.getName = function () {
console.log(this.name);
};
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法');
};
function Child() {}
Child.prototype = new Person(); // 原型链继承
const child1 = new Child();
const child2 = new Child();
child1.name = '大儿子';
child1.eats.push('香蕉');
console.log(child1);
child1.get();
console.log('---------------');
child2.name = '二儿子';
console.log(child2);
child2.get();
- 优点:
- 父类方法可以复用
- 缺点:
- 父类所有的引用类型数据(对象,数组)会被子类共享,更改一个子类的数据,其他子类也会受到影响
- 子类实例不能给父类构造函数传参
二,构造函数继承
实现方式: 在子类构造函数中用call函数修改父类构造函数的this
function Person() {
this.name = '小明'
this.eats = ['吃苹果']
this.getName = function () {
console.log(this.name)
}
}
// Person.prototype.get = () => {
// console.log('Person.prototype上的方法') // 不注释会报错
// }
function Child() {
Person.call(this)
}
const child1 = new Child()
const child2 = new Child()
child1.name = '大儿子'
child1.eats.push('香蕉')
console.log(child1)
// child1.get()
console.log('---------------')
child2.name = '二儿子'
console.log(child2)
// child2.get()
- 优点:
- 父类的引用类型不会被子类共享,不会互相影响
- 缺点:
- 子类不能访问父类原型属性上的方法和参数
三,组合继承
实现方法:原型链继承 + 构造函数继承
function Person() {
this.name = '小明'
this.eats = ['吃苹果']
this.getName = function () {
console.log(this.name)
}
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法')
}
function Child() {
Person.call(this)
}
Child.prototype = new Person()
const child1 = new Child()
const child2 = new Child()
child1.name = '大儿子'
child1.eats.push('香蕉')
console.log(child1)
child1.get()
console.log('---------------')
child2.name = '二儿子'
console.log(child2)
child2.get()
- 优点:
- 父类可以复用
- 父类构造函数中的引用属性不会被共享
- 缺点:
- 会调用两次父类的构造函数,会有两份一样的属性和方法,影响性能
四,寄生组合继承(最优解)
实现方法:
- 先用
call再子类的构造函数中修改父类的this - 定义一个中转的构造函数
Fn,将Fn的prototype与父类的prototype绑定到一起,再将子类的prototype指定为Fn的实例
function Person() {
this.name = '小明';
this.eats = ['吃苹果'];
this.getName = function () {
console.log(this.name);
};
}
Person.prototype.get = () => {
console.log('Person.prototype上的方法');
};前端构造函数的继承方式及其优缺点1111111111111111111111111111111111
function Child() {
Person.call(this);
}
const Fn = function () {};
Fn.prototype = Person.prototype;
Child.prototype = new Fn();
const child1 = new Child();
const child2 = new Child();
child1.name = '大儿子';
child1.eats.push('香蕉');
console.log(child1);
child1.get();
console.log('---------------');
child2.name = '二儿子';
console.log(child2);
child2.get();