在ES6中过滤或映射节点列表的最有效方法是什么?
根据我的读数,我会使用以下选项之一:
[...nodelist].filter
或
Array.from(nodelist).filter
你会推荐哪一个?还有更好的方法,例如不涉及数组吗?
答案 0 :(得分:66)
[...nodelist]
将从对象中生成一个数组。Array.from(nodelist)
和数字道具),则.length
将从对象中生成一个数组如果NodeList.prototype[Symbol.iterator]
存在,那么您的两个示例将是相同的,因为两个案例都涵盖了迭代。如果您的环境尚未配置为NodeList
可迭代,则第一个示例将失败,第二个示例将成功。 Babel
目前为does not handle this case properly。
因此,如果您的NodeList
是可迭代的,那么您自己决定使用它。我可能会根据具体情况选择。 Array.from
的一个好处是它需要映射函数的第二个参数,而第一个[...iterable].map(item => item)
必须创建一个临时数组,Array.from(iterable, item => item)
不会。但是,如果您没有映射列表,则无关紧要。
答案 1 :(得分:8)
TL; DR;
Array.prototype.slice.call(nodelist).filter
slice()方法返回一个数组。 返回的数组是一个浅的集合副本(NodeList) 因此它的工作速度比** Array.from()**
快原始集合的元素将复制到返回的数组中,如下所示:
有关参数的简短说明
Array.prototype.slice(beginIndex,endIndex)
Array.prototype.slice.call(namespace,beginIndex,endIndex)
答案 2 :(得分:4)
如何?
// 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)
与the MDN docs for NodeList.forEach(在“填充”下)所述的方法相同,它适用于IE11 ,Edge,Chrome和FF。
答案 3 :(得分:3)
我发现reference直接在NodeList上使用map
Array.prototype.map.call(nodelist, fn)
我还没有对它进行测试,但看起来似乎更快,因为它应该直接访问NodeList。
答案 4 :(得分:1)
在 ES6 中过滤或映射节点列表
我从这个简单的函数中脱颖而出。 @见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;}
我愿意了解更多:>