[英]Filter or map nodelists in ES6
在 ES6 中過濾或映射節點列表的最有效方法是什么?
根據我的讀數,我將使用以下選項之一:
[...nodelist].filter
或者
Array.from(nodelist).filter
你會推薦哪一個? 還有沒有更好的方法,例如不涉及數組?
[...nodelist]
將創建一個對象的數組,如果該對象是可迭代的。.length
和數字屬性Array.from(nodelist)
則Array.from(nodelist)
將從對象中創建一個數組如果NodeList.prototype[Symbol.iterator]
存在,您的兩個示例將是相同的,因為這兩種情況都涵蓋可迭代對象。 但是,如果您的環境尚未配置為使NodeList
可迭代,則您的第一個示例將失敗,而第二個示例將成功。 Babel
目前沒有正確處理這種情況。
因此,如果您的NodeList
是可迭代的,則完全取決於您使用哪個。 我可能會根據具體情況進行選擇。 Array.from
一個好處是它需要映射函數的第二個參數,而第一個[...iterable].map(item => item)
必須創建一個臨時數組Array.from(iterable, item => item)
不會。 但是,如果您沒有映射列表,則沒有關系。
TL; 博士;
Array.prototype.slice.call(nodelist).filter
slice() 方法返回一個數組。 返回的數組是集合 (NodeList) 的淺拷貝
所以它比
Array.from()工作得更快
所以它和Array.from()一樣快
原始集合的元素被復制到返回的數組中,如下所示:
關於論點的簡短解釋
Array.prototype.slice(beginIndex, endIndex)
Array.prototype.slice.call(命名空間,beginIndex,endIndex)
我找到了一個直接在 NodeList 上使用map
的參考
Array.prototype.map.call(nodelist, fn)
我還沒有測試過它,但是這看起來可能會更快,因為它應該直接訪問 NodeList。
這個怎么樣:
// Be evil. Extend the prototype.
if (window.NodeList && !NodeList.prototype.filter) {
NodeList.prototype.filter = Array.prototype.filter;
}
// Use it like you'd expect:
const noClasses = document
.querySelectorAll('div')
.filter(div => div.classList.length === 0)
它與NodeList.forEach 的 MDN 文檔(在“Polyfill”下)中提到的方法相同,它適用於 IE11 、Edge、Chrome 和 FF。
在 ES6 中過濾或映射節點列表
我從這個簡單的功能中走出來。 @see https://developer.mozilla.org/fr/docs/Web/API/NodeList/entries#exemple
function filterNodeList(NodeList, callback) {
if (!typeof callback === "function") callback = (i) => i; // Any have better idear?
const Result = document.createElement("div");
//# No need to filter empty NodeList
if (Node.length === 0) return Node;
for (let i = 0; i < Node.length; i++) {
if (callback(Node.item(i))) Result.appendChild(Node.item(i));
}
return Result.childNodes;}
我願意了解更多:>
[...a].filter
與Array.from(a).filter
不是“真正的”性能差異, Array.from
可能會快一點,因為您沒有在“JS 級別”上創建新的Array
,但它直接發生在本機代碼中。
但是,為了提高性能(並避免“ Array
-ing”),您應該考慮為什么要過濾NodeList
以及您從哪里/如何獲得它。 在許多情況下,您只需要按id
或按class
或其他 CSS 選擇器的特定元素。
document.querySelectorAll
快 10 倍 - 200 倍,適用於任何 CSS 選擇器
document.getElementById
甚至更快(但當然需要一個id
)
你甚至可以優化querySelectorAll
或繞過“未知”的情況,如果你提供一個預先存儲的父項來查看,讓我舉個例子:
let mainbar = document.getElementById('mainbar');
mainbar.querySelectorAll('.flex--item');
幾乎快 10 倍於
Array.from(a).filter(el => el.classList.contains("flex--item"))
還要注意document.querySelectorAll('#mainbar .flex--item');
仍然比Array
過濾快約 5 倍,但比使用id
預存儲父節點慢約 2 倍。
NodeList
(它可能是空的,但仍然是NodeList
),這適用於document.querySelectorAll()
和Element.querySelectorAll()
使用 ECMAS 2016:
let nodes = [...document.querySelector('__SELECTOR__').childNodes].filter(item => item.nodeType === 1);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.