Object.create(null)和{}
# Object.create(null) 和 {}
# What?
- 你可能经常看到这样的代码
const map = Object.create(null)
let obj = {}
1
2
3
2
3
- 上面的代码都是用来创建一个空对象,比如说我们需要用
obj
来存储数据,就可以如上面这样定义
总结: 这两个都是用来创建一个空对象
# Object.create()
方法简要介绍
MDN
解释:Object.create()
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
。- 也就是说
Object.create()
方法将创建一个新对象
,这个新对象
的原型指向你提供的参数
对象 - 我们看下面这个栗子

- 上面的栗子我们先创建了一个
person
对象 - 然后用
Object.create(person)
创建了一个 新对象,并将 新对象 赋值给obj
- 输出
obj
可以看到,obj
对象上自身为 空 ,而展开它的原型我们发现 :它的原型居然是 我们定义的person
- 再引用上面的一句话:
Object.create()
方法将创建一个新对象
,这个新对象
的原型指向你提供的参数
对象 Object.create()
还接受第二个参数,感兴趣的可以看看
# Why?
既然我们已经知道了 Object.create()
也是创建一个 新的空对象,直接用 {}
也是一个 空对象,那么我们为什么要用 Object.create(null)
呢?
我们继续以栗子来说明:
- 首先用
Object.create(null)
创建了 一个 新对象,并将其 赋值给empty
- 接着直接给
obj
赋值{}
- 我们输出
empty
和obj
- 展开之后发现
empty
下方有一行字No properties
--->没有属性
,而obj
有 原型对象,并且原型对象上有很多方法
结论: Object.create(null)
创建的 新对象 很干净,没有任何 多余的 东西,而 {}
有原型,原型上有很多方法
# How?
现在我们知道了 Object.create(null)
创建了一个 很干净的 新对象,那么我们为什么要这么做呢?
这里继续举个栗子
- 比如我们想要对数据去重进行优化
function removal(arr) {
let newArr = []
let obj = {}
arr.forEach((v) => obj[v] || ((obj[v] = true), newArr.push(v)))
return newArr
}
1
2
3
4
5
6
2
3
4
5
6
- 这里使用一个 中间变量
空对象obj
来 存储没有重复的数据 - 每一次循环 都要判断 在去重的
newArr
中有没有 这个值,如果没有则存入,有,则不存入 - 这样我们又需要 再次遍历
newArr
,增加了函数开销 - 而 用一个对象去存储,对象直接 以
key - value
的形式 存取值,不需要遍历,节省了开销 - 如果考虑对象属性查找规则,当前对象 自身上 没有就去
原型链
上查找,那么查找原型链
也需要开销。 - 更好的做法是:我们在 对象自身上 存的数据,只在 自身上 查找,所以 用
Object.create(null)
创建一个没有原型链
的空对象
,正好满足我们的要求 - 最后改一下我们栗子,如下
function removal(arr) {
let newArr = []
let obj = Object.create(null) // 没有 原型链 的空对象
arr.forEach((v) => obj[v] || ((obj[v] = true), newArr.push(v)))
return newArr
}
1
2
3
4
5
6
2
3
4
5
6
总结: Object.create(null)
创建一个 纯粹
的对象,以 防止原型污染
上次更新: 2021/03/25, 12:42:28