1. 原型链继承
function Parent() {
this.name = ‘parent‘
this.play = [1, 2, 3]
}
function Child() {
this.type = ‘child‘
}
Child.prototype = new Parent()
const a = new Child()
const b = new Child()
console.log(a.play === b.play) //true,因为两个实例通过原型链继承,使用的是同一个原型对象
2. 构造函数继承
function Parent(age) {
this.name = ‘parent‘;
this.age = age;
this.play = [1, 2, 3];
}
Parent.prototype.getName = function () {
return this.name;
};
function Child(age) {
Parent.call(this, age);
this.type = ‘child‘;
}
const a = new Child(20);
const b = new Child(30);
console.log(a.play === b.play); // false
console.log(a.getName()); // 报错,因为构造函数继承只是继承了构造函数里的属性,原型上的属性并未继承
3.组合继承
function Parent(age) {
this.name = ‘parent‘;
this.age = age;
this.play = [1, 2, 3];
}
Parent.prototype.getName = function () {
return this.name;
};
function Child(age) {
Parent.call(this, age);
this.type = ‘child‘;
}
Child.prototype = new Parent();
// 手动挂载构造器,指向自己的构造函数
Child.prototype.constructor = Child;
const a = new Child(1);
const b = new Child(10);
console.log(a instanceof Parent, a.play === b.play); // true,false
// 缺点:Parent 分别在构造函数上和原型链上都执行了一次,增加了性能开销
4.寄生组合继承
function Parent() {
this.name = ‘tom‘;
this.play = [1, 2, 3];
}
Parent.prototype.getName = function () {
return this.name;
};
function Child() {
Parent.call(this);
this.type = ‘child‘;
}
Child.prototype = Object.create(Parent.prototype); // 这里使用 Object.create() 节约一次实例化 Parent 的性能开销
Child.prototype.constructor = Child;
Child.prototype.getType = function () {
return this.type;
};
const a = new Child();
console.log(a.getName(), a.getType()); // tom child
JS 中的继承