Итерация через NodeList

Я ищу перспективный способ перебора NodeList (т.е. из element.querySelectorAll(selector)), а также совместимость с разными браузерами. Раньше я использовал функциональность ES6 Spread, однако IE не поддерживает распространение, поэтому вместо этого я использовал для этого прокладку. Я чувствовал, что это было немного излишним и неэффективным. Затем я наткнулся на хак Array.prototype.forEach.call. Работает, но мне кажется вонючим.

Как лучше всего перебирать NodeList?

Я неравнодушен к обратной совместимости и чистому коду, но если ваш ответ также работает по любому из других критериев ниже, это будет оценено.

  1. Читабельность
  2. Защита будущего
  3. Скорость

Я просмотрел итерацию JavaScript через 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);
});


person KGlasier    schedule 11.12.2019    source источник
comment
1. большинство читабельны. Это зависит от того, что вам удобно. Самый простой - это просто цикл for, но вы также можете использовать [].forEach.call, что я считаю идиоматичным. 2. Я не ожидаю, что какой-либо из них будет удален в будущем, поэтому я не уверен, почему вы хотите, чтобы это было более надежным в будущем, чем то, что уже работает сегодня. Если он работает в IE и современных браузерах, он будет работать и через годы. 3. Скорость, скорее всего, не имеет значения. Я сомневаюсь, что какой-либо общий метод остановит ваше приложение. Простая итерация редко является узким местом — проблемы с производительностью обычно возникают в другом месте.   -  person VLAZ    schedule 11.12.2019


Ответы (1)


Я рекомендую использовать полифилл MDN Array.from

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Polyfill

Array.from(nodeList).forEach(node => {})
person TKoL    schedule 11.12.2019
comment
Или просто [].prototype.slice.call(nodeList) Нет необходимости в полном полифилле, где все еще работает старый надежный способ преобразования массивов. Если вы не планируете использовать Array.from больше, включая другие типы вызовов, я полагаю. - person VLAZ; 11.12.2019
comment
Лично я делаю это для удобства чтения. Кто-то еще смотрит на мой код, [].prototype.slice.call немного непонятен по сравнению с Array.from() imo. Черт, даже если я просто смотрю на свой собственный код! - person TKoL; 11.12.2019
comment
Сейчас это распространенная идиома. Конечно, сторонний наблюдатель может быть сбит с толку, но... я думаю, они будут совершенно плохо знакомы с JS. Я не уверен, что написание кода для людей, не разбирающихся в языке, является хорошим способом, так как это отрезает вас от многих вещей, которые должны быть общими, но вы не можете использовать, потому что вы может сбить с толку других людей. Должны ли мы запретить использование document.querySelector, поскольку теперь кто-то может знать, что такое селекторы CSS? - person VLAZ; 11.12.2019
comment
.slice используется для копирования массивов: arr2 = arr1.slice(). Это был давний механизм копирования. call — это то, как вы вызываете метод с новой целью. Итак, он описывает себя как создание копии массива, используя это как цель - person VLAZ; 11.12.2019
comment
Нет, я знаю, что все это делает, это был риторический вопрос, чтобы описать, как не очевидно, что это делает, просто на словах. Я просто говорю, что в полной строке [].prototype.slice.call буквально нет ни одного слова, описывающего, что она делает. сделать копию массива, используя это как цель - ни одно из этих слов не находится в [].prototype.slice.call - person TKoL; 11.12.2019