如何创建一个没有原型的对象?
最开始的想法是:直接将新创建的对象的__proto__改为null就好了
追问:有什么方法可以直接拿到吗?
const specialObj = Object.create(null);
console.log(specialObj.__proto__); // undefined
继续追问:这个Object.create干了什么呢?能仿写一个吗?
Object.create方法用于创建一个新对象,使用现有的对象(传入的参数)来作为新创建对象的原型
function createObject(o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
追问:Object.create只能有一个参数吗?
// 可以有两个参数:
// proto: 新创建对象的原型对象
// propertiesObject: 如果该参数被指定且不为undefined,则该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应于Object.defineProperties()的第二个参数。
// 简单来说:第一个参数会是新对象的原型,第二个参数是新对象的属性
// Object.create(proto, propertiesObject)
// 案例:
let o = Object.create(Object.prototype, {
// foo is a regular 'value property'
foo: {
writable: true,
configurable: true,
value: 'hello'
},
// bar is a getter-and-setter (accessor) property
bar: {
configurable: false,
get: function() { return 10; },
set: function(value) {
console.log('Setting `o.bar` to', value);
}
}
})
console.log(o)
// 得到:
// {bar: 10, foo: "hello", get bar: ƒ (), set bar: ƒ (value), [[Prototype]]: Object }
继续追问:既然提到了原型,那么写一下寄生组合式继承吧
// 实现寄生组合式函数继承核心函数之一:原型继承式函数(旧写法需要用到)
function createObject(o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
// 实现寄生组合式函数继承核心函数之一:寄生式继承
function inheritPrototype(SubType, SuperType) {
// 旧的写法
SubType.prototype = createObject(SuperType.prototype)
// 新的写法
// SubType.prototype = Object.create(SuperType.prototype)
// 这一步是为了让新创建的原型对象中的constructor指向先前的构造函数
Object.defineProperty(SubType.prototype, "constructor", {
enumerable: false,
configurable: true,
writable: true,
value: SubType
})
}