所以我想要一种简单的方法来循环遍历节点列表,我总是讨厌我不能在节点列表上使用forEach
。
所以,现在我做:Array.prototype.forEach.call(nodeList, callback)
。
对于索引,我这样做:Array.prototype.indexOf.call(nodeList, node)
。
对于我在nodeLists上使用Array.prototype的几乎所有内容。
但我想知道这些是否被视为黑客攻击?
他们是正确的做法吗?
另外,假设我实际上并不需要来自nodeList的数组,那么使用Array.from(nodeList).forEach(callback)
是否有优势呢?
答案 0 :(得分:3)
Array.prototype.forEach.call(nodeList, callback)
将在节点列表中应用forEach
的逻辑。 forEach
只有一个for
循环,从索引0
到this.length
并在每个项目上调用回调。此方法调用forEach
将节点列表作为其this
值传递,因为节点列表具有类似的数组属性(length
和0
,1
, ...),一切正常。
Array.from(nodeList).forEach(callback)
将从节点列表创建一个新数组,然后在该新数组上使用forEach
。第二种方法可以分为两个自解释线:
var newArray = Array.from(nodeList); // create a new array out of the node list
newArray.forEach(callback); // call forEach on the new array
第一种方法更好,因为它不会创建额外的不需要的资源,而且它可以直接在节点列表上工作。
答案 1 :(得分:3)
第一种方法是ES5兼容:
Array.prototype.forEach.call(nodeList, callback).
第二种方法使用仅在ES6中定义的Array.from
:
Array.from(nodeList).forEach(callback)
但是,您没有在此优化Array.from
的使用,因为您首先创建整个数组,然后使用forEach
进行迭代。
而是使用Array.from
的第二个参数:
Array.from(nodeList, callback)
现在整个操作都在一次迭代中发生。
好处是在上面的表达式中,回调用作映射函数,因此如果它返回一个值,则整个表达式返回由这些返回值定义的数组。但使用它当然是可选的。例如,您可以创建一个包含节点文本内容的数组,如下所示:
texts = Array.from(nodeList, node => node.textContent)
答案 2 :(得分:2)
var array=Array.from(nodeList);
//after some time
var array2=Array.from(nodeList);
如果比较这些阵列,你会发现它们不一定相等。 NodeLists反映了DOM的变化,当你复制它们时,数组保持静态。如果你想要这种行为/不关心你很好。但是 Array.from 是相当新的,因此它不被旧版浏览器所理解,所以它不应该在生产环境中使用(如果你不像Babel那样使用它)。