document.querySelectorAll的返回类型是什么

时间:2014-02-11 22:45:44

标签: javascript html

假设我有以下列表:

  <ol>
    <li>Cookies <ol>
    <li>Coffee</li>
    <li>Milk</li>
    <li class="test1">Chocolate </li>
   </ol>

我在html结尾处执行此选择

 var nodes = document.querySelectorAll('li:first-of-type');

当我在Chrome nodes.forEach中尝试时,它给了我一个错误。当我看到它看起来像一个数组的值。我实际上能够使用常规来导航它,如:

for(var i=0;i<nodes.length;i++){
   nodes[i].onclick= function(){ alert('Hello!'); };
} 

那么,document.querySelectorAll的实际返回类型是什么?为什么数组方法不起作用?

所以,它看起来像一个数组,可以解决它使它像数组一样工作,但它不是一个数组?

2 个答案:

答案 0 :(得分:9)


结果的类型是NodeList。 由于它是一个类似于Array的对象,你可以像这样运行mapforEach和其他Array.prototype函数:

var result = document.querySelectorAll('a');
Array.prototype.map.call(result, function(t){ return t; })

Array原型中的mapforEachany和其他函数适用于类似Array的对象。例如,让我们定义一个具有数字索引(0,1)和长度属性的对象文字:

var arrayLike = { '0': 'a', '1': 'b', length: 2};

应用于arrayLike对象的forEach方法将类似于真实数组。

Array.prototype.forEach.call(arrayLike, function(x){ console.log(x) } ); //prints a and b

答案 1 :(得分:5)

documentation中,它说:

  

[返回的元素列表]是元素对象的非实时NodeList

NodeList与数组(完全不同的原型链)不同,文档还告诉您为什么不能使用forEach

  

为什么我无法在forEach上使用mapNodeList

     

NodeList与数组非常相似,并且很容易对它们使用Array.prototype方法,但它们没有这些方法。

     

JavaScript有一个基于原型的继承机制,用于内置对象(如Array s)和宿主对象(如NodeList s)。 Array个实例继承了数组方法(例如forEachmap),因为它们的原型链如下所示:

     

myArray --> Array.prototype --> Object.prototype --> null(对象的原型链可以通过多次调用Object.getPrototypeOf来获得。)

     

forEachmap等都是Array.prototype对象的自有属性。

     

与数组不同,NodeList原型链如下所示:

     

myNodeList --> NodeList.prototype --> Object.prototype --> null

     

NodeList.prototype包含item方法,但不包含Array.prototype方法,因此无法在NodeLists上使用。

但是,有一些解决方法。再次从文档中,您可以直接使用Array.prototype.forEachArray.prototype.map方法:

var forEach = Array.prototype.forEach;

var divs = document.getElementsByTagName( 'div' );
var firstDiv = divs[ 0 ];

forEach.call(firstDiv.childNodes, function( divChild ){
  divChild.parentNode.style.color = '#0F0';
});