{}、new Object()、Object.Create(null)区别

83 阅读3分钟

先讲一下遇到的问题:{},new Object()以及Object.create(null)的区别

{}、new Object()、Object.Create(null)区别

1、{}, new Object()

{}、new Object()是一样的,都是继承Object,继承Object原型方法和属性。

image.png

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中打印如下:

image.png

从图中可以看到,a继承了Object的属性和方法,在新对象上可以直接使用。

再看看Object.create()方法:

var o = Object.create(null,{
    a:{
        writable:true,
        configurable:true,
        value:'1'
    }
})
console.log(o) 

在chrome控制台打印如下:

image.png

这个是上面讲到的无属性对象,同时也不继承Object的属性和方法。

我们再改一改

var o = Object.create({},{
    a:{
        writable:true,
        configurable:true,
        value:'1'
    }
})
console.log(o) 

null改为{},结果是怎样的?在chrome控制台打印如下:

image.png 这里和const a = { a: 1}的结果已经很接近了,区别是这里多了一层__proto__嵌套。

我们改一下

var o = Object.create(Object.prototype,{
    a:{
        writable:true,
        configurable:true,
        value:'1'
    }
})
console.log(o) 

chrome控制台打印如下:

image.png

这次就和使用{}创建的对象一模一样了。

结论: {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 } })