原型链继承
/**
* 原型链继承
* 子类原型指向父类的实例对象
* 问题:引用值共享问题
* 使用 借用构造函数继承解决此问题
*/
/**
* 父类构造函数
*/
function Person() {
this.arr = [1, 2, 3];
}
/**
* 子类构造函数
*/
function Sub() {}
Sub.prototype = new Person();
const sub1 = new Sub();
const sub2 = new Sub();
sub1.arr.push(4);
console.log("sub1", sub1.arr); // [1, 2, 3, 4]
console.log("sub2", sub2.arr); // [1, 2, 3, 4]
构造函数继承
/**
* 借用构造函数继承
* 子类构造函数内执行父类 call改变this指向
* 问题:无法继承父类原型上的属性和方法
* 使用组合继承解决此问题
*/
/**
* 父类构造函数
*/
function Person() {
this.arr = [1, 2, 3];
}
Person.prototype.say = function () {
console.log("say!!!");
};
/**
* 子类构造函数
*/
function Sub() {
Person.call(this);
}
const sub1 = new Sub();
const sub2 = new Sub();
sub1.arr.push(4);
console.log(sub1.arr); // [1, 2, 3, 4]
console.log(sub2.arr); // [1, 2, 3]
sub1.say(); // Uncaught TypeError: sub1.say is not a function
sub2.say(); // Uncaught TypeError: sub1.say is not a function
组合继承
/**
* 组合继承(伪经典继承)
* 问题:父类构造函数复用问题(父类构造函数会被多次调用)
* 使用寄生组合继承
*/
/**
* 父类构造函数
*/
function Person() {
this.arr = [1, 2, 3];
}
Person.prototype.say = function () {
console.log("say!!!");
};
/**
* 子类构造函数
*/
function Sub() {
Person.call(this);
}
Sub.prototype = new Person();
const sub1 = new Sub();
const sub2 = new Sub();
sub1.arr.push(4);
console.log(sub1.arr); // [1, 2, 3, 4]
console.log(sub2.arr); // [1, 2, 3]
sub1.say(); // say!!!
sub2.say(); // say!!!
寄生组合继承
/**
* 寄生组合继承(经典继承)
*/
/**
* 父类构造函数
*/
function Person() {
this.arr = [1, 2, 3];
}
Person.prototype.say = function () {
console.log("say!!!");
};
/**
* 子类构造函数
*/
function Sub() {
Person.call(this);
}
Sub.prototype = Object.create(Person.prototype);
const sub1 = new Sub();
const sub2 = new Sub();
sub1.arr.push(4);
console.log(sub1.arr); // [1, 2, 3, 4]
console.log(sub2.arr); // [1, 2, 3]
sub1.say(); // say!!!
sub2.say(); // say!!!