只写了一个寄生式组合继承,其可以算是引用类型继承的最佳模式,注重过程还是能学习到很多知识点。
function Parent(name) {
this.name = name
}
Parent.prototype.getName = function () {
return this.name
}
function Child(name, age) {
// 构造函数继承
Parent.call(this, name)
this.age = age
}
/**
* Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的 __proto__
*
* @param proto
* @param properties
* @returns {F}
*/
function myObjectCreate(proto, properties) {
if (typeof proto !== 'object' && proto !== null) {
throw new TypeError('Object prototype may only be an Object or null')
}
function F() {}
F.prototype = proto
const f = new F()
if (proto === null) {
Object.setPrototypeOf(f, proto)
}
const isObject = o => Object.prototype.toString.call(o) === '[object Object]'
if (isObject(properties)) {
for (let key in properties) {
if (Object.prototype.hasOwnProperty.call(properties, key) && !isObject(properties[key])) {
throw new TypeError('Property description must be an object')
}
}
Object.defineProperties(f, properties)
}
return f
}
// 寄生式继承
Child.prototype = myObjectCreate(Parent.prototype, {
getAge: {
enumerable: true,
configurable: true,
writable: true,
value: function () {
return this.age
}
},
like: {
enumerable: true,
configurable: true,
writable: true,
value: 'coding'
}
})
Object.defineProperty(Child.prototype, 'constructor', {
enumerable: false,
configurable: false,
writable: false,
value: Child
})
const c = new Child('bo', 100)
验证一波
// 实例对象的 __proto__ 指向的是创建它的构造函数的 prototype 对象
console.log(Child.__proto__ === Function.prototype) // true
console.log(Child.prototype.__proto__ === Parent.prototype) // true
console.log(Parent.prototype.__proto__ === Object.prototype) // true
console.log(Object.prototype.__proto__ === null) // true