原文: https://zswfx.com/articles/5da713302ddd022595ff506a
咱們在使用 Array.prototype.splice
方法的時候,都會說起說它速度慢,效率低。尤爲在例如 Vue
或者React
框架中也不推薦使用,緣由是爲何呢?javascript
方法介紹以下:vue
方法也比較明瞭,就是在數組內刪除或者添加元素。
以下示例:java
// 添加一個元素 const arr = [1, 2, 3] arr.splice(1, 0, 2, 3) // [1, 2, 3, 2, 3] // 刪除元素 arr.splice(2, 2) // arr: [1, 2, 3]
返回值則是刪除元素的數組,如果添加就是空數組.react
在 w3c 中關於 splice 是如何描述過程的呢?數組
Array.prototype.splice 位於ecmascript 規範中 15.4 數組章節下面的 15.4.4.12 點擊這了便可
下面看關於 splice描述:
框架
下面就用刪除和添加兩個例子來講明規範的操做過程:ecmascript
在規範裏面共有 17步的數據操做:性能
actualDeleteCount > 0
即爲刪除,而後獲得A的刪除數組,這裏就獲取到了要刪除的元素,若刪除元素個數爲0,則跳過A爲空數組,k 爲0, 不然 k爲刪除個數,A 爲刪除元素集合. actualStart 爲傳入的數組中某個下標值, actualDeleteCount 爲傳入某個個數範圍是 0-len 在 splice
方法中,咱們會使用狀況以下:es5
刪除元素在第9步處理刪除元素數組,第12步處理元素前移並刪除結尾的元素。添加元素在13步內處理元素後移,並在15步在對應下標下放入元素。刪除元素同時刪除上面每一步都會走到。spa
關於規範一些內部方法說明:
[[HasProperty]](P) 對象上的內部方法,若經過P獲得對象結果爲undefined則爲false,不然爲true。
[[GET]](P) 對象內部方法,經過屬性名P獲取結果。
[[Put]](P, V, Throw) 設置對象屬性P的值爲V,Throw若爲true,遇到錯誤則會拋出TypeError。
[[Delete]](P, Throw) 刪除對象上屬性P,若Throw爲true,遇到錯誤則拋出TypeError.
操做數組:
[0, 1, 2, 3]
這裏進行 splice(1, 2, 4)
操做,從下標1位置移除2個元素,並添加一個元素
[0, 1, 2, 3]
進行 splice(1, 1, 5, 6)
操做,從下標1的位置刪除一個元素,並插入 5和6
的示例。
經過上面規範分析和圖示分析,其實splice之因此」慢「
, 是由於每次splice操做除了須要分配新的內存區域去存儲數據外,還須要不斷操做元素的下標,大量移動元素位置,若start=0,豈不是每一個元素都須要移動一次呢?這就是說效率不高緣由。
tips: splice 會修改數組自己,因此在vue和react中數組數據變化不會致使UI變化的緣由之一。
其餘參考:
https://www.jianshu.com/p/483...
上面說splice 用於三種狀況:
在最新的ecma中有新的方法能夠替代splice用途
使用 filter
代替:
const arr = [1, 2, 3, 4] // 刪除下標爲2的元素 const newArray = arr.filter((_, index) => index !== 2) // [1, 2, 4]
使用 concat
或者 spread
代替配合 slice
實現任何位置插入:
const array = [1, 2, 3,] // 下標1 插入10 const newArray = array.slice(0, 1).concat(10, array.slice(1)) // [1, 10, 2, 3] // const newArray = [...array.slice(0, 1), 10, array.slice(1)]
同上
const array = [0, 1, 2, 3, 4, 5] // 下標位置2位置刪除2個,並插入7,8,9 const newArray = array.slice(0, 2).concat([7, 8, 9], array.slice(4)) // [0, 1, 7, 8, 9, 4, 5]
相信本身,總會有一個辦法解決問題,代碼性能也會一點點提升,歡迎交流。