先讲一下遇到的问题:{},new Object()以及Object.create(null)的区别
{}、new Object()、Object.Create(null)区别
1、{}, new Object()
{}、new Object()是一样的,都是继承Object,继承Object原型方法和属性。
2、Object.create(null)
Object.create()是用来创建一个新对象,使用现有的对象来提供新对象的proto
Object.create(proto,[propertiesObject])
- proto:新创建对象的原型对象
- propertiesObject:可选。要添加到新对象的可枚举(新添加的属性是其自身的属性,而不是其原型链上的属性)的属性。
let Obj = {
name: null,
age: null,
info: function() {
console.log(`我的名字叫${this.name},我永远${this.age}岁!`);
}
}
let p1 = Object.create(Obj);
p1.name = "lokka";
p1.age = 18;
p1.info(); // 我的名字叫lokka,我永远18岁!
那么我们说回 Object.Create(null) , Object.Create(null) 继承一个 null,null里面什么都没有,所以就会创建一个干净的对象,也就不用考虑和原型链上的属性或者方法重名的问题。
小结一下
字面量和new关键字创建的对象是Object的实例,原型指向Object.prototype,继承内置对象Object
Object.create(proto,[propertiesObject])创建的对象的原型取决于proto,proto为null,新对象是空对象,没有原型,不继承任何对象;arg为指定对象,新对象的原型指向指定对象,继承指定对象
再对比一下:
Object.create()、{…}的区别
默认情况下我们创建一个对象:
const a = { a: 1}
在chrome中打印如下:
从图中可以看到,a继承了Object的属性和方法,在新对象上可以直接使用。
再看看Object.create()方法:
var o = Object.create(null,{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
在chrome控制台打印如下:
这个是上面讲到的无属性对象,同时也不继承Object的属性和方法。
我们再改一改
var o = Object.create({},{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
将null改为{},结果是怎样的?在chrome控制台打印如下:
这里和
const a = { a: 1}的结果已经很接近了,区别是这里多了一层__proto__嵌套。
我们改一下
var o = Object.create(Object.prototype,{
a:{
writable:true,
configurable:true,
value:'1'
}
})
console.log(o)
chrome控制台打印如下:
这次就和使用{}创建的对象一模一样了。
结论: {a: 1} 等价于Object.create(Object.prototype, {a: 1})
什么情况下使用Object.create(null)
需要一个纯净的map且高度定制的数据字典时使用,可以在此基础上定义自己的hasOwnProperty、toString方法,同时不用当心原型链上同名的方法或者属性被覆盖掉。
另一个理由是,我们在for- in的时候会遍历原型链上的属性,使用create(null)创建的对象,for-in时就不会有这样的问题,当然我们也可以使用Object.keys(obj)来遍历对象的key值。或者说想节省hasOwnProperty带来的一丢丢性能损失并且可以偷懒少些一点代码的时候。
【严肃脸】我一般不用,都是大佬们在用。
自己实现一个Object.create()
//实现一个Object.create()方法
Object.myCreate = function (proto, propertiesObject) {
if (proto === null) {
throw new Error("This browser does not support the Object.create method.");
}
let object = {}
Object.setPrototypeOf(object, proto);
if (propertiesObject != null) {
Object.defineProperties(object, propertiesObject);
}
return object;
}
const person = Object.myCreate({ name: 'fiona' }, { age: { value: 2 } })