Skip to content

Instantly share code, notes, and snippets.

@satouriko
Last active January 19, 2022 00:42
Show Gist options
  • Save satouriko/93ac5357d1f70037a1fba92f8592b0f7 to your computer and use it in GitHub Desktop.
Save satouriko/93ac5357d1f70037a1fba92f8592b0f7 to your computer and use it in GitHub Desktop.
寄生式组合继承
// 定义构造函数(初始化属性)
function Animal(type) {
this.type = type
}
// 定义原型(初始化方法)
Animal.prototype = {
eat() {
console.log('eat')
}
}
Animal.prototype.constructor = Animal
// 子类构造函数先调用父类构造函数
function Human() {
Animal.call(this, 'human')
}
// 子类原型继承自父类原型
// Object.create 创建一个原型为 Animal.prototype 的实例
// 类似于 new Animal() 但不调用 Animal 的构造函数
Human.prototype = Object.assign(Object.create(Animal.prototype), {
speak() {
console.log('speak')
}
})
Human.prototype.constructor = Human
// 定义抽象构造函数
function Animal(type) {
if (new.target === Animal) {
throw new Error('Animal cannot be directly instantiated')
}
if (typeof this.mate !== 'function') {
throw new Error('Animal must have a way to reproduce children')
}
this.type = type
}
// 定义抽象原型
Animal.prototype = {
eat() {
console.log('eat')
}
}
Animal.prototype.constructor = Animal
// 子类构造函数先调用父类构造函数
function Human() {
Animal.call(this, 'human')
}
// 子类原型必须声明抽象方法
Human.prototype = Object.assign(Object.create(Animal.prototype), {
mate() {
console.log('mate')
},
speak() {
console.log('speak')
}
})
Human.prototype.constructor = Human
// 立即调用函数表达式: 相当于一个可以求值的块
const Person = function () {
// 使用 Symbol 作为私有属性的键,来避免被访问
// 实际上还是可以通过 Object.getOwnPropertySymbols 访问
const $name = Symbol('name')
const $love = Symbol('love')
// 私有方法
const _love = function () {
console.log('I love you when you call me ' + this[$name])
}
// 私有静态变量
const _people = []
return class {
constructor(name) {
this[$name] = name // 使用 Symbol 隐藏的私有属性
this[$love] = _love // 把私有方法添加到 this 上以便调用时绑定 this
_people.push(this)
console.log(_people)
}
get name() {
this[$love]()
return this[$name]
}
set name(_name) {
this[$name] = _name
}
}
}()
@satouriko
Copy link
Author

经典继承 - 指子类通过调用父类构造函数来继承
组合式继承 - 指组合了原型链和经典继承,该方法中以父类的实例化作为子类原型,故有两次调用父类构造函数的问题
原型继承 - 通过创建以父类原型为原型的对象来继承,该方法不调用父类构造函数
寄生式继承 - 指原型继承的工厂模式,它不调用父类的构造函数,是为“寄生构造函数”
寄生式组合继承 - 实质上是组合了「原型继承」和「经典继承」的方法,本例中为简化说明去除了其工厂模式的部分

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment