2

Я использую babel-polyfill и я пытаюсь перебирать в HTMLCollection объект, используя для-петли:Итерация объект HTMLCollection используя для петли-

const elements = document.getElementsByClassName('some-class') 
for (const element of elements) { 
    console.log(element) 
} 

Это не работает. Я получаю сообщение об ошибке elements[Symbol.iterator] is not a function. Как заставить его работать правильно?

+0

Чтобы объяснить несколько вещей, которые вы неправильно поняли: core-js является частью babel-polyfill, поэтому нет смысла включать его дважды. Если написание команды 'Symbol.iterator' в консоли работает, это означает только, что этот символ существует; это не обязательно означает, что 'elements' имеют свойство' Symbol.iterator'. for-loop не рассматривает ничего как массив - он просто вызывает метод '@@ iterator' объекта. –

+0

Также, если вы не знаете, что такое объект HTMLCollection: это объект, возвращаемый 'document.getElementsByClassName()'. –

+0

@ Gothdo, чтобы уточнить, я никогда не включал в себя как core-js, так и babel-polyfill: я только что попробовал импортировать их в разное время, чтобы увидеть, будет ли тот или другой работать. Тем не менее, спасибо за разъяснение. – thesublimeobject

ответ

3

От "Iterable DOM collections" on the core-js GitHub page:

Некоторые коллекции DOM должны iterable interface или должны быть inherited from Array. Это означает, что они должны иметь keys, values, entries и @@iterator методы для итерации. Поэтому добавьте их. Модуль web.dom.iterable:

{ 
    NodeList, 
    DOMTokenList, 
    MediaList, 
    StyleSheetList, 
    CSSRuleList 
} 
    #values()  -> iterator 
    #keys()  -> iterator 
    #entries() -> iterator 
    #@@iterator() -> iterator (values) 

Как вы можете видеть, что список не включает в себя HTMLCollection. Чтобы иметь возможность использовать цикл for-loop с HTMLCollection, вам необходимо вручную назначить Array.prototype.values на HTMLCollection.prototype[Symbol.iterator]. Смотрите пример:

HTMLCollection.prototype[Symbol.iterator] = Array.prototype.values 
 

 
for (const element of document.getElementsByTagName('a')) { 
 
    console.log(element.href) 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js"></script> 
 
<a href="//www.google.com">Google</a> 
 
<a href="//www.github.com">GitHub</a>

В качестве альтернативы, вы можете просто использовать document.querySelectorAll(), которой возвращает NodeList объект.

+0

@ zer00ne Добавлен ответ. –

+0

@ Gothdo Это чрезвычайно полезный ответ. Большое спасибо. Я неправильно понял итеративную спецификацию, и теперь понимаю, почему у меня возникла эта проблема. – thesublimeobject