开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
寄生组合式继承
要求
补全JavaScript代码,要求通过寄生组合式继承使"Chinese"构造函数继承于"Human"构造函数。要求如下:
- 给"
Human"构造函数的原型上添加"getName"函数,该函数返回调用该函数对象的"name"属性 - 给"
Chinese"构造函数的原型上添加"getAge"函数,该函数返回调用该函数对象的"age"属性
思路
寄生组合式继承是引用类型最理想的继承范式,它融合了组合式继承与寄生式继承的优点,而组合式继承又是融合了原型链和借用构造函数的技术,从而发挥两者之长,所以寄生组合式继承实际是三种技术的融合。
- 寄生式继承的思路是:创建一个仅用于封装继承过程的函数
- 组合式继承的思路是:使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
这一题的思路是:
- 先创建一个inheritPrototype函数,该函数属于寄生式继承模式,作用是实现实现对原型属性和方法的继承:
// subType子类构造函数,superType父类构造函数
function inheritPrototype(subType,superType){
// Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。
var prototype = Object.create(superType.prototype); // 创建父类型的一个副本对象
prototype.constructor = subType; // 修复prototype的constructor
subType.prototype = prototype; // 将prototype设为subType的原型
}
这里涉及到原型链的知识:一个构造函数的prototype指向它的原型对象,而它的原型对象的constructor属性又指向到这个构造函数。上面的代码中因为要让prototype设置为subType的原型,所以prototype.constructor需要指向到subType。
调用inheritPrototype后,subType就继承了superType的属性和方法,这些属性和方法存在于subType的原型上,这样一来subType的所有实例就能访问到同一个存在的属性或方法(这些属性和方法相当于是公有的)。
- 给"
Human"构造函数的原型上添加"getName"函数:
Human.prototype.getName=function (){
return this.name;
}
- 通过借用构造函数来实现
Chinese对Human实例属性的继承:
function Chinese(name,age) {
// 继承了Human,还传了参数
Human.call(this,name); // 借用构造函数模式
this.age = age;
this.color = 'yellow';
}
在Chinese内部调用Human构造函数,实际上是为Chinese的实例设置了Human上具有的属性和方法(不包含Human原型上的属性和方法),这样一来Chinese的所有实例就能拥有自己的属性和方法(这些属性和方法相当于是私有的)。
- 调用
inheritPrototype(Chinese,Human);来实现Chinese对Human原型属性和方法的继承。 - 给"
Chinese"构造函数的原型上添加"getAge"函数:
Chinese.prototype.getAge=function(){
return this.age;
}
代码
var prototype = Object.create(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
function Human(name) {
this.name = name
this.kingdom = 'animal'
this.color = ['yellow', 'white', 'brown', 'black']
}
Human.prototype.getName = function () {
return this.name;
}
function Chinese(name,age) {
Human.call(this,name);
this.age = age;
this.color = 'yellow';
}
inheritPrototype(Chinese,Human);
Chinese.prototype.getAge = function() {
return this.age;
}