背景:
什么是继承: 如果B继承了A,那么B就是A的子类,好处是子类可以使用父类的方法和属性,可覆盖,可重写
继承的实现:
1组:
- 原型链继承:
- 如果原型上有引用对象: 会共享内存
- 构造函数继承:
- 解决了1的问题,但无法继承 父类 原型对象 上的方法和属性
- 组合继承:前两个的组合,但子类的原型上有父类方法属性,子类上也有父类方法属性,执行了2遍
2组:使用Object.create(指定的原型对象)进行继承
- 原型继承:存在共享对象问题
- 寄生继承:语法上优化1,但是还是有共享的问题
- 寄生组合继承(最优解):ES6的extends就是这个实现,为了解决1组的问题,也为了解决2组前两种方式
代码:
- 父类:
function Parent(){
this.arr = [1,2,3];
this.name = 'parent1';
}
Parent.prototype.getName = function () {
return this.name;
}
Parent.prototype.school = {
name:"小学"
}
1组代码:
1.1 原型链继承:
ProChainChild.prototype = new Parent();
function ProChainChild(){
this.name = '我是子类'
}
// !!!! 子类实现了对父类的继承
ProChainChild.prototype = new Parent();
let pro_child1 = new ProChainChild();
let pro_child2 = new ProChainChild();
pro_child1.arr.push(4);
console.log("1.原型链继承:原型属性会被共享", pro_child1.arr, pro_child2.arr, pro_child1.school);
1.2 构造函数继承:为了解决1使用构造函数继承:
Parent.call(this);
// !!!!!子类对父类的继承
function Child1(){
Parent.call(this);
this.name = '我是构造函数继承的子类';
}
let new_child = new Child1();
let new_child1 = new Child1();
new_child1.arr.push(4)
console.log("2.构造函数继承:不继承父类原型链上的属性和方法", new_child.arr, new_child1.arr, new_child.school)
1.3 组合继承(1+2):
Parent.call(this); +ChildGroup.prototype = new Parent();
function ChildGroup(){
// !!!!! 子类实现继承2
Parent.call(this);
this.name = '我是组合继承的子类';
}
// !!!!! 子类实现继承1
ChildGroup.prototype = new Parent();
let group_child = new ChildGroup();
let group_child1 = new ChildGroup();
group_child1.arr.push(4);
console.log("3.组合继承:执行2次parent", group_child.arr, group_child1.arr, group_child.school)
2组代码:
2.1 寄生组合继承:最优解
为了解决组1的所有问题Parent.call(this);+ Object.create(Parent.prototype)
function ChildParGroup(){
// !!!!! 子类实现继承
Parent.call(this);
this.name = '我是寄生组合继承的子类';
}
ChildParGroup.prototype.age = 18;
// !!!!! 子类实现继承
ChildParGroup.prototype = Object.create(Parent.prototype); // 创建一个空对象, 并指向某个原型对象
ChildParGroup.prototype.constructor = ChildParGroup;
let pro_group_child = new ChildGroup();
let pro_group_child1 = new ChildGroup();
pro_group_child1.arr.push(4);
console.log("4.寄生组合继承:child 原型上的属性和方法会丢失", pro_group_child.arr, pro_group_child1.arr, pro_group_child.school, pro_child1.age)
2.2 原型式继承:
有共享问题
let parent4 = {
name: "parent4",
friends: ["p1", "p2", "p3"],
getName: function() {
return this.name;
}
};
let person4 = Object.create(parent4);
2.3 寄生式继承:
2.2 的优化,但依然有共享问题
let parent5 = {
name: "parent5",
friends: ["p1", "p2", "p3"],
getName: function() {
return this.name;
}
};
function clone(original) {
let clone = Object.create(original);
clone.getFriends = function() {
return this.friends;
};
return clone;
}