使用JavaScript的forEach方法,我们可以轻松的循环一个数组,但如果你认为document.querySelectorAll()
方法返回的应该是个数组,而使用forEach
循环它:
/* Will Not Work */
document.querySelectorAll('.module').forEach(function() {
// do something
});
执行上面的代码,你将会得到执行错误的异常信息。这是因为,document.querySelectorAll()
返回的不是一个数组,而是一个NodeList
。
对于一个NodeList,我们可以用下面的技巧来循环遍历它:
var divs = document.querySelectorAll('div');
[].forEach.call(divs, function(div) {
// do whatever
div.style.color = "red";
});
当然,我们也可以用最传统的方法遍历它:
var divs = document.querySelectorAll('div'), i;
for (i = 0; i < divs.length; ++i) {
divs[i].style.color = "green";
}
还有一种更好的方法,就是自己写一个:
// forEach method, could be shipped as part of an Object Literal/Module
var forEach = function (array, callback, scope) {
for (var i = 0; i < array.length; i++) {
callback.call(scope, i, array[i]); // passes back stuff we need
}
};
// 用法:
// optionally change the scope as final parameter too, like ECMA5
var myNodeList = document.querySelectorAll('li');
forEach(myNodeList, function (index, value) {
console.log(index, value); // passes index + value back!
});
还有一种语法:for..of 循环,但似乎只有Firefox支持:
/* Be warned, this only works in Firefox */
var divs = document.querySelectorAll('div );
for (var div of divs) {
div.style.color = "blue";
}
最后是一种不推荐的方法:给NodeList扩展一个forEach方法:
NodeList.prototype.forEach = Array.prototype.forEach;
var divs = document.querySelectorAll('div').forEach(function(el) {
el.style.color = "orange";
})
循环 NodeList
,因为 document.querySelectorAll()
返回的并不是我们想当然的数组,而是 NodeList
,对 NodeList
,它里面没有 .forEach
方法,我们使用了这样的方法进行循环:
var divs = document.querySelectorAll('div');
[].forEach.call(divs, function(div) {
// do whatever
div.style.color = "red";
});
初次看到 [].forEach.call()
这样的代码,我觉得这种写法很有趣,为什么要这样写?为什么要用空数值引申出的方法?于是研究了一下。
[]
就是个数组,而且是用不到的空数组。用来就是为了访问它的数组相关方法,比如 .forEach
。这是一种简写,完整的写法应该是这样:
Array.prototype.forEach.call(...);
很显然,简写更方便。
至于 forEach
方法,它可以接受一个函数参数:
[1,2,3].forEach(function (num) { console.log(num); });
上面的这句代码中,我们可以访问 this
对象,也就是 [1,2,3]
,可以看出,这个 this
是个数组。
最后, .call
是一个prototype
,JavaScript函数内置的。 .call
使用它的第一个参数替换掉上面说的这个 this
,也就是你要传人的数组,其它的参数就跟 forEach
方法的参数一样了。
[1, 2, 3].forEach.call(["a", "b", "c"], function (item, i, arr) {
console.log(i + ": " + item);
});
// 0: "a"
// 1: "b"
// 2: "c"
因此, [].forEach.call()
是一种快速的方法访问 forEach
,并将空数组的 this
换成想要遍历的list。