遍历NodeList

5
我正在寻找一种未来证明的方式来迭代NodeList(例如从element.querySelectorAll(selector)),同时也要跨浏览器兼容。 以前,我使用了ES6 Spread功能,但是IE不支持扩展,因此我改用了它的shim。 我觉得那有点过度和低效。 然后我发现了hack Array.prototype.forEach.call。 它能工作,但看起来对我来说有点臭。

迭代NodeList的最佳方法是什么?

我偏爱向后兼容性和代码清晰,但如果您的答案也适用于以下任何其他标准,那将不胜感激。

  1. 可读性
  2. 未来证明
  3. 速度

我查看了JavaScript iterate through NodeList,其中介绍了一些方法。 但是,并没有关注可读性,兼容性等问题。 只关注是否有效。

我遇到的一些方法包括:

const elems = document.querySelectorAll('img');

[].forEach.call(elems, function (o) { console.log(o) });

[...elems].foreach(function (o) { console.log(o) });

for (var i = 0; i < elems.length; i++) {
    console.log(elems[i]);
}

for (var i = elems.length - 1; i >= 0; i--) {
    console.log(elems[i]);
}

// User-defined
var forEach = function (array, callback, scope) {
    for (var i = 0; i < array.length; i++) {
        callback.call(scope, i, array[i]);
    }
};
forEach(elems, function (index, value) {
    console.log(index, value);
});


  1. 大多数都是可读的。这取决于你自己的舒适度。最简单的方法就是使用 for 循环,但你也可以选择 [].forEach.call,我认为这是惯用法。
  2. 我不希望任何一个被删除,所以我不确定为什么你希望它比现在已经运行的更加“未来化”。如果它在IE和现代浏览器上运行良好,那么它将在未来几年内继续工作。
  3. 速度可能不是一个问题。我怀疑任何常见的方法都不会使你的应用程序停滞不前。简单的迭代很少成为瓶颈 - 性能问题通常出现在其他地方。
- VLAZ
2个回答

6

或者只需使用[].prototype.slice.call(nodeList)。不必提供完整的多重填充(polyfill)来转换数组相似对象,因为旧的可靠方法仍然有效。除非你打算经常使用Array.from,包括它的其他类型调用,我想。 - VLAZ
出于可读性的考虑,我个人会这样做。如果有人查看我的代码,相对于 Array.from()[].prototype.slice.call 看起来有点晦涩难懂。甚至就算只是我自己查看我的代码也是如此! - TKoL
现在这是一种常见的惯用语。当然,一个局外人可能会感到困惑,但我猜他们对JS还是完全陌生的。我不确定为不熟悉该语言的人编写代码是否是一种好方法,因为它会使您失去很多本应该是常见的东西,但您无法使用,因为您可能会让其他人感到困惑。因为某人可能不知道CSS选择器,我们应该禁止使用document.querySelector吗? - VLAZ
.slice 用于复制数组:arr2 = arr1.slice()。这是一个长期存在的复制机制。call 是用新目标调用方法的方式。因此,它描述自己为“使用此作为目标来复制数组”。 - VLAZ
不,我知道它都做什么,那只是一个修辞问题,用来描述从这些单词中很难看出具体功能。我的意思是[].prototype.slice.call完整的字符串里没有一个单词可以描述它所做的工作。“使用这个作为目标创建一个数组副本” — 这些单词都不能解释[].prototype.slice.call - TKoL

0
以下对我来说完全没问题:
[].map.call(nodeList, item => {})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接