Chr*_*phe 52 javascript arrays filter nodelist ecmascript-6
在ES6中过滤或映射节点列表的最有效方法是什么?
根据我的读数,我会使用以下选项之一:
[...nodelist].filter
Run Code Online (Sandbox Code Playgroud)
要么
Array.from(nodelist).filter
Run Code Online (Sandbox Code Playgroud)
你会推荐哪一个?有没有更好的方法,例如没有涉及数组?
log*_*yth 80
[...nodelist] 如果对象是可迭代的,将生成一个对象的数组.Array.from(nodelist)如果对象是可迭代的,或者如果对象是类似数组(有.length和数字道具),将从对象中生成一个数组如果NodeList.prototype[Symbol.iterator]存在,您的两个示例将是相同的,因为两个示例都涵盖了迭代.如果您的环境尚未配置NodeList为可迭代,则第一个示例将失败,第二个示例将成功.Babel目前无法正确处理此案例.
因此,如果您NodeList的可迭代性,那么您使用它真的取决于您.我可能会根据具体情况选择.一个好处Array.from是它需要映射函数的第二个参数,而第一个[...iterable].map(item => item)必须创建一个临时数组,Array.from(iterable, item => item)不会.但是,如果您没有映射列表,则无关紧要.
gow*_*eon 14
我找到了一个直接在 NodeList 上使用的引用map
Array.prototype.map.call(nodelist, fn)
Run Code Online (Sandbox Code Playgroud)
我还没有测试过它,但它看起来可能会更快,因为它应该直接访问 NodeList。
Ser*_*kyy 12
TL; DR;
Array.prototype.slice.call(nodelist).filter
Run Code Online (Sandbox Code Playgroud)
slice()方法返回一个数组.返回的数组是一个浅的集合副本(NodeList) 所以它的工作速度比**Array.from()**快
原始集合的元素将复制到返回的数组中,如下所示:
关于论点的简短解释
Array.prototype.slice(beginIndex,endIndex)
Array.prototype.slice.call(namespace,beginIndex,endIndex)
[...a].filter与Array.from(a).filter性能上没有“真正”的差异,Array.from可能会快一点,因为您不是Array在“JS 级别”创建新的,但它直接发生在本机代码中。
然而,为了性能(并避免“ Array-ing”),您应该考虑为什么要过滤 aNodeList以及您从哪里/如何获得它。id在许多情况下,您只需要通过或通过或其他 CSS 选择器来获取特定元素class。
document.querySelectorAll速度快了10 倍 - 200 倍,适用于任何 CSS 选择器
document.getElementById甚至更快(但当然需要id)
如果您提供预存储的父级来查看,您甚至可以优化querySelectorAll或绕过“未知”情况,让我给您举个例子:
let mainbar = document.getElementById('mainbar');
mainbar.querySelectorAll('.flex--item');
Run Code Online (Sandbox Code Playgroud)
几乎快 10 倍
Array.from(a).filter(el => el.classList.contains("flex--item"))
Run Code Online (Sandbox Code Playgroud)
另请注意,这document.querySelectorAll('#mainbar .flex--item');仍然比Array过滤快约 5 倍,但比使用id.
NodeList(它可能是空的,但它仍然会是NodeList),这对于两者都document.querySelectorAll()适用Element.querySelectorAll()这个怎么样:
// 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)
Run Code Online (Sandbox Code Playgroud)
它与NodeList.forEach 的 MDN 文档(在“Polyfill”下)中提到的方法相同,它适用于 IE11、Edge、Chrome 和 FF。
| 归档时间: |
|
| 查看次数: |
26580 次 |
| 最近记录: |