Почему getElementsByClassName в JavaScript предоставляет объект, который НЕ является массивом?

Я пытаюсь получить список в JavaScript (не используя jQuery) всех элементов на странице с определенным именем класса. Поэтому я использую функцию getElementsByClassName() следующим образом:

var expand_buttons = document.getElementsByClassName('expand');
console.log(expand_buttons, expand_buttons.length, expand_buttons[0]);

Обратите внимание, что на моей странице есть три элемента привязки с классом «расширить». Этот console.log() выводит

[] 0 undefined

Далее, для прикола, я закинул expand_buttons в собственный массив следующим образом:

var newArray = new Array(expand_buttons);
console.log(newArray, newArray.length);

Это внезапно выводит

[NodeList[3]] 1

и я могу щелкнуть список узлов и увидеть атрибуты трех элементов привязки «расширить» на странице. Также стоит отметить, что мне удалось заставить мой код работать на тестовой странице w3schools< /а>.

Также можно отметить, что мое использование document.getElementsByName фактически выводит (на консоль) массив элементов, но когда я запрашиваю его длину, он сообщает мне 0. Точно так же, если я пытаюсь получить доступ к элементу массива, используя array_name[0] как обычно, он выводит «undefined», несмотря на то, что внутри массива явно есть элемент, когда я вывожу объект на консоль.

Кто-нибудь знает, почему это может быть? Я просто хочу перебирать элементы DOM, и в данный момент я избегаю jQuery, потому что пытаюсь практиковать кодирование с помощью ванильного JavaScript.

Спасибо,

ПарагонРГ


person Paragon    schedule 16.06.2012    source источник
comment
проверьте, не изменилась ли эта функция   -  person neu-rah    schedule 16.06.2012
comment
Вы запускаете свой код после создания DOM или до?   -  person Damien_The_Unbeliever    schedule 16.06.2012
comment
Будьте осторожны с w3schools.   -  person Pointy    schedule 16.06.2012
comment
Дополнительные объяснения   -  person Ravi Kadaboina    schedule 16.06.2012


Ответы (2)


Это не столько вещь JavaScript, сколько вещь веб-браузера. Этот API предоставляется собственным объектом (объект document) и по спецификации DOM возвращает объект NodeList. Вы можете рассматривать NodeList как массив, и он похож, но явно отличается (как вы заметили).

Вы всегда можете скопировать NodeList в новый массив:

var nodeArr = Array.prototype.slice.call(theNodeList, 0);

или в современных средах ES2015:

var nodeArr = Array.from(theNodeList);

JavaScript всегда существует в каком-то контексте времени выполнения, и этот контекст может включать в себя все виды API, которые предоставляют возможности для кода JavaScript. Веб-браузер является одним из таких контекстов. DOM указан таким образом, что это не особенно касается JavaScript; это определение интерфейса, не зависящее от языка.

Я предполагаю, что короткая версия этого ответа будет «потому что это просто так».

person Pointy    schedule 16.06.2012
comment
Если вы можете использовать ES2015/ES6, тогда Array.from ваш друг - person mfeineis; 30.04.2017

Он не возвращает массив, потому что объект, который он возвращает, является "живым", в частности, это живой NodeList:

В большинстве случаев NodeList представляет собой живую коллекцию. Это означает, что изменения в дереве DOM будут отражаться в коллекции.

person Damien_The_Unbeliever    schedule 16.06.2012