为何说在 JS 中要避免使用 delete

在 JavaScript 中 delete 操做符用于删除对象的某个属性。例如编程

const person = {
    name: 'sudada',
    gender: 'female'
}

delete person.name

console.log(person.name) // undefined
复制代码

与最直观的语义不一样,使用 delete 操做符并不会直接释放内存,而是说它会使得 V8(Javascript)引擎中的 hidden class 失效,将该 object 变为一个通用的 slow object,这就使得执行速度有了很明显的下降。jsp

hidden class:因为 JavaScript 是一种动态编程语言,属性可进行动态的添加和删除,这意味着一个对象的属性是可变的,大多数的 JavaScript 引擎(V8)为了跟踪对象和变量的类型引入了隐藏类的概念。在运行时 V8 会建立隐藏类,这些类附加到每一个对象上,以跟踪其形状/布局。这样能够优化属性访问时间。编程语言

参考:布局

debuggable.com/posts/under…post

stackoverflow.com/questions/4…优化

那么若是不使用 delete ,咱们如何删除对象的属性?ui

最有效的方式,应该是将不须要的属性设置为 undefined ,例如spa

const person = {
    name: 'sudada',
    gender: 'female'
}

person.name = undefined // 删除 name 属性
复制代码

或者你也能够考虑使用 Spread Operator for objects,例如debug

const person = {
    name: 'sudada',
    gender: 'female'
}
const omit = (prop, { [prop]: _, ...rest }) => rest;
const newObj = omit('name', person); // 删除 name 属性
复制代码

关于 Spread Operator for objects 的参考:juejin.im/post/5c35bd…rest

那么 delete、设置为 undefinedomit 三种方法该如何抉择?

图中显示了,在不一样的 Javascript 内核下,三种方法的效率(每秒执行数)。能够很明显地得出一个结论,设置为 undefined > delete > omit

实例地址:jsperf.com/removing-va…

可是设置为 undefined,获得的结果为

{
    name: undefined,
    gender: 'female'
}
复制代码

有时须要额外的操做,例如

JSON.parse(JSON.stringify(person))
// 或者
Object.keys(person).reduce((pre, cur) => {
    const value = person[cur]
    return value === undefined ? pre : {...pre, [cur]: value}
}, {})
复制代码

这样效率会大幅度地下降,因此在实际业务中能够考虑使用 Map 来代替 object ,例如

let map = new Map([['a', 1]])
let obj = { a: 1 };
// 执行
delete obj.a;
map.delete('a');
复制代码

从图中,能够很明显的得出 map.delete 优于 delete

相关文章
相关标签/搜索