爲何說在 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 會建立隱藏類,這些類附加到每一個對象上,以跟蹤其形狀/佈局。這樣能夠優化屬性訪問時間。

參考:編程語言

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

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

那麼若是不使用 delete ,咱們如何刪除對象的屬性?優化

最有效的方式,應該是將不須要的屬性設置爲 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 的參考: https://juejin.im/post/5c35bd...

那麼 delete、設置爲 undefinedomit 三種方法該如何抉擇?3d

圖片描述

圖中顯示了,在不一樣的 Javascript 內核下,三種方法的效率(每秒執行數)。能夠很明顯地得出一個結論,設置爲 undefined > delete > omitrest

實例地址: 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

相關文章
相關標籤/搜索