实现 Object.create
手写 Object.create 方法
问题
从零实现 Object.create 方法,创建一个以指定对象为原型的新对象。
解答
基础实现
function objectCreate(proto) {
// 参数校验:proto 必须是对象或 null
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object or null')
}
// 创建空构造函数
function F() {}
// 将构造函数的原型指向传入的对象
F.prototype = proto
// 返回新实例,该实例的 __proto__ 指向 proto
return new F()
}
完整实现(支持属性描述符)
function objectCreate(proto, propertiesObject) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object or null')
}
function F() {}
F.prototype = proto
const obj = new F()
// 处理 null 原型的情况
if (proto === null) {
obj.__proto__ = null
}
// 如果传入了属性描述符,使用 defineProperties 添加属性
if (propertiesObject !== undefined) {
Object.defineProperties(obj, propertiesObject)
}
return obj
}
测试
const person = {
greet() {
console.log(`Hello, I'm ${this.name}`)
}
}
// 基础用法
const tom = objectCreate(person)
tom.name = 'Tom'
tom.greet() // Hello, I'm Tom
console.log(Object.getPrototypeOf(tom) === person) // true
// 带属性描述符
const jerry = objectCreate(person, {
name: {
value: 'Jerry',
writable: true,
enumerable: true
},
age: {
value: 18,
writable: false
}
})
jerry.greet() // Hello, I'm Jerry
console.log(jerry.age) // 18
// null 原型(纯净对象)
const dict = objectCreate(null)
console.log(dict.toString) // undefined,没有继承 Object.prototype
关键点
- 核心原理:借助空构造函数,将其 prototype 指向目标原型,再 new 出实例
- 参数校验:proto 只能是对象或 null,否则抛出 TypeError
- null 原型:创建的对象不继承任何属性,适合用作纯净的字典
- 第二个参数:属性描述符对象,通过
Object.defineProperties实现 - 与
{}的区别:{}原型是Object.prototype,Object.create(null)原型是 null
目录