为什么说在 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,这就使得执行速度有了很明显的降低。

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

参考:

http://debuggable.com/posts/u...:4c7e81e4-1330-4398-8bd2-761bcbdd56cb

https://stackoverflow.com/que...

那么如果不使用 delete ,我们如何删除对象的属性?

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

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

person.name = undefined // 删除 name 属性

或者你也可以考虑使用 Spread Operator for objects,例如

const person = {
    name: 'sudada',
    gender: 'female'
}
const omit = (prop, { [prop]: _, ...rest }) => rest;
const newObj = omit('name', person); // 删除 name 属性
关于 Spread Operator for objects 的参考:https://juejin.im/post/5c35bd...

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

图片描述

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

实例地址:https://jsperf.com/removing-v...

但是设置为 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

67 声望
4 粉丝
0 条评论
推荐阅读
React-sortable-hoc 结合 hook 实现 Draggin 和 Droppin
翻译:[链接] React 社区提供了许多的库来实现拖放的功能,例如 react-dnd, react-beautiful-dnd, react-drag-n-drop,等等。但是它们有一些共同的缺陷: 使用复杂,有时候需要做很多工作才能构建一个简单的拖放...

Gepangz11阅读 14.8k评论 3

从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木140阅读 11.9k评论 10

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木60阅读 5.9k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.1k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木39阅读 7.1k评论 6

【关于Javascript】--- 正则表达式篇
基础知识一、元字符 {代码...} 二、量词 {代码...} 三、集合 字符类 {代码...} 四、分支 {代码...} 五、边界 开始结束 {代码...} 六、修饰符 {代码...} 七、贪婪模式和非贪婪模式js默认贪婪模式即最大可能的匹配...

Jerry35阅读 2.9k

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木32阅读 6k评论 9

67 声望
4 粉丝
宣传栏