Concat 适用于普通数值和字符串数组,但不适用于对象数组。
实际上,它确实如此,但NodeList
实例没有concat
方法,Array#concat
也没有办法识别您想要展平那些(因为它们不是数组)。
但这仍然很容易做到(不过,请参阅下面的警告)。更改此行:
var allTags = allInputs.concat(allSelects);
至
var allTags = [];
allTags.push.apply(allTags, allInputs);
allTags.push.apply(allTags, allSelects);
实例| 资源
这通过使用一些技巧来工作:Array#push
接受可变数量的元素添加到数组中,并Function#apply
使用给定的值this
(在我们的例子中,allTags
)和任何类似数组的对象作为传递给它的参数调用函数. 由于NodeList
实例是类似数组的,因此很push
乐意将列表的所有元素推送到数组中。
这种行为Function#apply
(不需要第二个参数真的是一个数组)在规范中非常明确地定义,并且在现代浏览器中得到很好的支持。
遗憾的是,IE6 和 7 不支持上述内容(我认为它专门使用主机对象——NodeLists
作为Function#apply
的第二个参数),但是,我们也不应该支持它们。:-) IE8 也没有,这更有问题。IE9 对此很满意。
如果您需要支持 IE8 及更早版本,可悲的是,我认为您会遇到一个无聊的旧循环:
var allInputs = document.getElementsByTagName('input');
var allSelects = document.getElementsByTagName('select');
var allTags = [];
appendAll(allTags, allInputs);
appendAll(allTags, allSelects);
function appendAll(dest, src) {
var n;
for (n = 0; n < src.length; ++n) {
dest.push(src[n]);
}
return dest;
}
实例| 资源
这确实适用于 IE8 及更早版本(以及其他)。