遍历 NodeList:Array.prototype.forEach.call() vs Array.from().forEach
Loop through NodeList: Array.prototype.forEach.call() vs Array.from().forEach
所以我想要一个简单的方法来遍历节点列表,我一直讨厌我不能在节点列表上使用 forEach
。
所以,现在我这样做:Array.prototype.forEach.call(nodeList, callback)
。
对于索引,我这样做:Array.prototype.indexOf.call(nodeList, node)
。
几乎所有我都在 nodeLists 上使用 Array.prototype。
但我想知道这些是否被认为是黑客?
它们是正确的方法吗?
此外,假设我实际上不需要来自 nodeList 的数组,那么使用 Array.from(nodeList).forEach(callback)
是否有优势?
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
第一种方法更好,因为它不会创建额外的不需要的资源,而且它直接作用于节点列表。
var array=Array.from(nodeList);
//after some time
var array2=Array.from(nodeList);
如果比较这些数组,您会发现它们不一定相等。 NodeLists 反映了 DOM 的变化,当你复制它们时,数组保持静态。如果你想要这种行为/不关心你很好。然而 Array.from 是相当新的,因此它不被旧浏览器理解,所以它不应该在生产环境中使用(如果你不使用像 Babel 这样的东西)。
第一种方法兼容ES5:
Array.prototype.forEach.call(nodeList, callback).
第二种方法使用Array.from
,它只在ES6中定义:
Array.from(nodeList).forEach(callback)
但是,您并未在此处优化 Array.from
的使用,因为您首先创建了整个数组,然后使用 forEach
.
对其进行迭代
而是使用 Array.from
的第二个参数:
Array.from(nodeList, callback)
现在整个操作在一次迭代中发生。
好的是,在上面的表达式中,回调被用作映射函数,所以如果它return是一个值,整个表达式returns 由那些 return 值定义的数组。但是使用它当然是可选的。例如,您可以创建一个包含节点文本内容的数组,如下所示:
texts = Array.from(nodeList, node => node.textContent)
所以我想要一个简单的方法来遍历节点列表,我一直讨厌我不能在节点列表上使用 forEach
。
所以,现在我这样做:Array.prototype.forEach.call(nodeList, callback)
。
对于索引,我这样做:Array.prototype.indexOf.call(nodeList, node)
。
几乎所有我都在 nodeLists 上使用 Array.prototype。
但我想知道这些是否被认为是黑客?
它们是正确的方法吗?
此外,假设我实际上不需要来自 nodeList 的数组,那么使用 Array.from(nodeList).forEach(callback)
是否有优势?
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
第一种方法更好,因为它不会创建额外的不需要的资源,而且它直接作用于节点列表。
var array=Array.from(nodeList);
//after some time
var array2=Array.from(nodeList);
如果比较这些数组,您会发现它们不一定相等。 NodeLists 反映了 DOM 的变化,当你复制它们时,数组保持静态。如果你想要这种行为/不关心你很好。然而 Array.from 是相当新的,因此它不被旧浏览器理解,所以它不应该在生产环境中使用(如果你不使用像 Babel 这样的东西)。
第一种方法兼容ES5:
Array.prototype.forEach.call(nodeList, callback).
第二种方法使用Array.from
,它只在ES6中定义:
Array.from(nodeList).forEach(callback)
但是,您并未在此处优化 Array.from
的使用,因为您首先创建了整个数组,然后使用 forEach
.
而是使用 Array.from
的第二个参数:
Array.from(nodeList, callback)
现在整个操作在一次迭代中发生。
好的是,在上面的表达式中,回调被用作映射函数,所以如果它return是一个值,整个表达式returns 由那些 return 值定义的数组。但是使用它当然是可选的。例如,您可以创建一个包含节点文本内容的数组,如下所示:
texts = Array.from(nodeList, node => node.textContent)