构造继承(构造继承有多种实现方式)
借用构造函数的技术(有时候也叫做伪造对象或经典继承)。这种技术的基本思想相当简单,即在子类构造函数内部调用超类构造函数。
冒充继承
function Person(name, age){
this.name = name
this.age = age
this.showName = function(){
console.log('我是' + name)
}
}
function Child(){
this.temp = Person // 创建一个自身缓存函数, 并将父类函数作为它的值
this.temp('ysg', 18) // 执行缓存函数,即执行父类函数
delete this.temp // 删除缓存函数
}
绑定this方式实现
function Child(){
Person.bind(this)('ysg', 18) // 绑定this到Person运行环境执行函数
}
call方式实现
function Child(){
Person.call(this, 'ysg', 18)
}
apply方式实现
function Child(){
Person.apply(this, ['ysg', 18])
}
原型继承
function Person(name, age){
this.name = name
this.age = age
}
Person.prototype.showName = function(){
console.log(this.name)
}
function Student(){}
Student.prototype = new Person('ysg', 18)
const stu = new Student()
stu.showName()
组合方式
组合继承,有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥两者之长的一种继承模式。
其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。 这样,即通过在原型上定义方法实现了函数的复用,又能够保证每个实例都有它自己的属性。
function SuperType(name){
this.name = name
this.colors = ["red", "blue", "green"]
}
SuperType.prototype.sayName = function(){
console.log(this.name)
}
function SubType(name, age){
// 继承属性
SuperType.call(this, name)
this.age = age
}
// 继承方法
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
寄生继承
寄生式继承是与原型式继承紧密相关的一种思路,并且同样也是由克罗克福德推而广之。寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象。
function createAnother(original) {
const clone = Object(original) // 通过调用函数来创建一个新对象
clone.sayHi = function(){ // 以某种方式来增强这个对象
alert('hi')
}
return clone // 返回这个对象
}
const person = {
name : 'ysg',
age : 18
}
const anotherPerson = createAnother(person)
anotherPerson.sayHi()
寄生组合方式
寄生组合式继承,即通过借用构造函数来继承属性, 通过原型链的混成形式来继承方法。
其背后的基本思想是:不必为了指定子类型的原型而调用超类型的构造函数, 我们所需要的无非就是超类型原型的一个副本而已。 本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
function inheritPrototype(subType, superType){
const prototype = Object(superType.prototype) // 父函数原型创建副本
prototype.contructor = subType
subType.prototype = prototype // 子函数的的原型
}
function SuperType(name){
this.name = name
this.colors = ["red", "blue", "green"]
}
SuperType.prototype.sayName = function(){
alert(this.name)
}
function SubType(name, age){
SuperType.call(this, name)
this.age = age
}
inheritPrototype(SubType, SuperType)