javascript - 在 ES6 中篩選或映射節點列表
在 ES6 中過濾或映射 nodelist 最有效的方法是什麼?
根據我的閱讀,我會使用以下其中一個選項:
[...nodelist].filter
或
Array.from(nodelist).filter
你會推薦哪一個?有沒有更好的方法,例如不涉及陣列的方式?
答案#1
[...nodelist]如果物件是可迭代的,將會把物件變成陣列。Array.from(nodelist)將會把一個物件轉換成陣列,如果該物件是可迭代的 或者 如果該物件類似陣列(有.length和數字屬性)
如果存在 NodeList.prototype[Symbol.iterator],你的兩個例子將是相同的,因為這兩種情況都涵蓋了可迭代對象。然而,如果你的環境沒有配置使 NodeList 可迭代,你的第一個例子將失敗,而第二個將成功。Babel 目前無法正確處理這種情況。
所以如果你的 NodeList 是可迭代的,究竟使用哪一個真的取決於你。我可能會根據具體情況來選擇。Array.from 的一個好處是它可以接受第二個參數作為映射函數,而第一種 [...iterable].map(item => item) 會必須創建一個臨時陣列,Array.from(iterable, item => item) 則不需要。不過如果你沒有對列表做映射,那麼哪種方式都無所謂。
答案#2
我找到了一個引用,直接在 NodeList 上使用 map
Array.prototype.map.call(nodelist, fn)
我還沒有測試過,但這看起來是合理的,因為它應該會直接訪問 NodeList,因此速度可能會更快。
答案#3
太長;不看
Array.prototype.slice.call(nodelist).filter
slice() 方法會回傳一個陣列。該回傳的陣列是集合(NodeList)的淺層複本 所以它的執行速度比 Array.from() 快 所以它的執行速度和 Array.from() 一樣快
原集合的元素被複製到返回的陣列中,如下所示:
- 對於物件參考(而不是實際的物件),slice 會將物件參考複製到新的陣列中。原始陣列和新的陣列都指向同一個物件。如果被參考的物件發生變化,這些變化對新陣列和原始陣列都是可見的。
- 對於字串、數字和布林值(不是 String、Number 和 Boolean 物件),slice 會將值複製到新的陣列中。對一個陣列中的字串、數字或布林值的更改不會影響另一個陣列。
關於論點的簡短說明
Array.prototype.slice(beginIndex, endIndex)
- 接受可選的參數 beginIndex 和 endIndex。如果未提供它們,slices 將使用 beginIndex == 0,因此它會從集合中提取所有項目
Array.prototype.slice.call(namespace, beginIndex, endIndex)
- 將一個物件作為第一個參數。如果我們使用集合作為物件,它字面上的意思是我們直接從該物件調用 slice 方法 namespace.slice()
