最近在看框架源码的时候,发现作者(或者Contributors)创建对象的时候,或者做继承的时候,都喜欢用到Object.create()。
首先MDN上对这个方法介绍的很清楚了,
Object.create(proto[, propertiesObject])
第一个参数传一个对象,(ps:[]为可选参数),MDN释义为"新创建对象的原型对象",一般传xx.prototype,如果直接传对象,会多嵌套一层__proto__,eg:
var o = Object.create({},{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
可以看到下图,因为__proto__隐式原型就指向的是构造函数的原型对象,如果直接传xx.prototype就没有下面问题。
第二个参数propertiesObject为则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。具体哪些可枚举属性,可以再去查defineProperties()这个方法的第二个参数,一般有个value值即为我们对象最后的value值,其他属性为配置相关的参数,比如可读可写之类的。
理解到上面的之后,使用Object.create一个很重要的原因是,我们可以通过create(null)来创建一个"干净"的对象。
eg:
传入null后,新创建的对象没有任何属性。不用担心自定义的属性把原型链上的覆盖掉。eg,我们自定义了a对象,想检查a.hasOwnProperty属性,a.toString属性,我们如果用{}创建,就不能直接通过a.toString,a.hasOwnProperty直接访问,因为原型上的属性会干扰,如果要检查toString属性,我们之前是用Object.prototype.hasOwnProperty.call(a,'toString')来做校验,这样的方式即麻烦,又浪费了一点性能,for in遍历的时候还需要做校验。(当然可以使用Object.keys)
使用还是要看场景,除非需要非常干净高度可定制的对象(传null后甚至不能称之为对象了可以称为数据字典,因为没有继承到Object上共享的方法),否者还是用{}吧。