11.手写原型式继承、寄生式继承、寄生组合式继承
webVueBlog opened this issue · 0 comments
原型式继承
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
在函数内部,先创建 临时性的构造函数,然后将传入的对象作为这个 构造函数的原型,最后返回这个临时构造函数的一个实例。从本质上,该函数对传入的对象执行了一次 浅拷贝。
ECMAScript 5 通过增加 Object.create()方法
这个方法接收两个参数:作为新对象原型的对象,以及给新对象定义额外属性的对象(第二个可选)
let person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
let anotherPerson = Object.create(person, {
name: {
value: "Greg"
}
});
console.log(anotherPerson.name); // "Greg"
场景:
原型式继承非常适合不需要单独创建构造函数,但仍然需要在对象间共享信息的场合
缺点:
属性中包含的引用值始终会在相关对象间共享,跟使用原型模式是一样的。(引用类型值的属性始终都会共享相应的值,多个实例对象对引用类型的操作会被篡改。)
原型式继承是借助原型基于已有的对象创建新对象,同时还不必因此创建自定义类型。
function Person(friendship) {
function Creator() {}
Creator.prototype = friendship;
return new Creator();
}
寄生式继承
寄生式继承背后的思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,以某种方式增强对象,然后返回这个对象。
function createAnother(original){
let clone = object(original); // 通过调用函数创建一个新对象
clone.sayHi = function() { // 以某种方式增强这个对象
console.log("hi");
};
return clone; // 返回这个对象
}
场景:
寄生式继承同样适合主要关注对象,而不在乎类型和构造函数的场景。(在主要考虑对象而 不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。)
寄生式继承(Parasitic Inheritance):创建一个仅用于封装继承过程的函数,在函数内部以某种方式增强对象
function creator(origin) {
// 以 origin 为原型对象创建一个新对象
let clone = Object.create(origin);
// 以某种方式来增强这个对象
clone.sayHi = function () {
console.log('Hello world!');
};
// 返回这个对象
return clone;
}
寄生式组合继承
寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。
(寄生式组合继承通过盗用构造函数继承属性,但使用混合式原型链继承方法。)
组合继承的例子:
function SubType(name, age){
SuperType.call(this, name); // 第二次调用 SuperType()
this.age = age;
}
SubType.prototype = new SuperType(); // 第一次调用 SuperType()
function inheritPrototype(subType, superType) {
let prototype = object(superType.prototype); // 创建对象
prototype.constructor = subType; // 增强对象
subType.prototype = prototype; // 赋值对象
}
不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。 本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
function inherit(child, parent) {
// 创建对象
let prototype = Object.create(parent.prototype);
// 增强对象
prototype.constructor = child;
// 指定对象
child.prototype = prototype;
}
这个函数接收两个参数:子类型构造函数 和 超类型构造函数。
寄生式组合继承可以算是引用类型继承的最佳模式。