在ES6中筛选或映射节点列表

时间:2015-09-24 15:21:22

标签: javascript arrays filter ecmascript-6 nodelist

在ES6中过滤或映射节点列表的最有效方法是什么?

根据我的读数,我会使用以下选项之一:

[...nodelist].filter

Array.from(nodelist).filter

你会推荐哪一个?还有更好的方法,例如不涉及数组吗?

5 个答案:

答案 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()**

原始集合的元素将复制到返回的数组中,如下所示:

  • 对于对象引用(而不是实际对象),slice将对象引用复制到新数组中。原始数组和新数组都引用相同的对象。如果引用的对象发生更改,则更改对新的和原始数组都可见。
  • 对于字符串,数字和布尔值(不是String,Number和Boolean对象),slice会将值复制到新数组中。对一个数组中的字符串,数字或布尔值的更改不会影响另一个数组。

有关参数的简短说明

Array.prototype.slice(beginIndex,endIndex)

  • 采用可选的args beginIndex和endIndex。 如果未提供切片,则切片使用beginIndex == 0,因此它将从集合中提取所有项目

Array.prototype.slice.call(namespace,beginIndex,endIndex)

  • 将对象作为第一个参数。如果我们使用集合作为对象,它实际上意味着我们直接从该对象调用slice方法 namespace.slice()

答案 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;}

我愿意了解更多:>