为什么 JavaScript 的 getElementsByClassName 返回的不是一个数组?

6

我正在尝试使用JavaScript(不使用jQuery)获取带有特定类名的所有元素列表。 因此,我使用getElementsByClassName()函数如下:

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

请注意,我的页面上有三个带有类“expand”的锚元素。此console.log()输出结果:
[] 0 undefined

接下来,只是为了好玩,我将expand_buttons放入了它自己的数组中,如下所示:
var newArray = new Array(expand_buttons);
console.log(newArray, newArray.length);

这突然输出。
[NodeList[3]] 1

我可以通过节点列表单击并查看页面上三个“expand”锚元素的属性。值得注意的是,我能够在w3schools测试页面中使我的代码工作。

可能值得注意的是,我的document.getElementsByName实际上确实会输出一个元素数组(到控制台),但当我询问它的长度时,它告诉我是0。同样,如果我按照正常情况下使用array_name[0]来访问数组元素,它会输出'undefined',尽管在将对象打印到控制台时清楚地存在一个元素。

有没有人知道这可能是为什么?我只想循环遍历DOM元素,而且目前避免使用jQuery,因为我正在练习使用原生JavaScript编写代码。

谢谢,

ParagonRG


检查该函数是否未被更改。 - neu-rah
1
你是在 DOM 构建完成后还是之前运行代码? - Damien_The_Unbeliever
1
小心使用w3schools。(http://w3fools.com) - Pointy
更多解释 - Ravi Kadaboina
2个回答

10

这不仅仅与JavaScript有关,更是与Web浏览器有关。该API由本地对象(document对象)提供,并且根据DOM规范返回一个NodeList对象。您可以像操作数组一样处理NodeList对象,它们很相似,但又有明显的区别(正如您所注意到的那样)。

您总是可以将NodeList复制到新数组中:

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

或在现代ES2015环境中:

var nodeArr = Array.from(theNodeList);

JavaScript总是存在于某个运行环境中,该环境可以包括各种API,为JavaScript代码提供便利的功能。Web浏览器就是其中之一。DOM的规范并不特别偏向JavaScript;它是一个语言中立的接口定义。

我想简短回答这个问题的版本应该是,“因为它本来就存在于其中。”


1
如果您可以使用ES2015/ES6,那么Array.from就是您的好朋友。 - mfeineis

3
它不返回数组,因为它返回的对象是“实时的”,具体来说,它是一个实时NodeList

在大多数情况下,NodeList是一个实时集合。这意味着DOM树上的更改将反映在集合中。


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