在JavaScript中合并两个对象(NodeList)数组

use*_*797 10 javascript arrays merge object

我试图合并两个对象数组,以便我可以验证表单.通常的concat方法似乎在这种情况下不起作用.Concat适用于普通的数字和字符串数组,但不适用于对象数组.这条线var allTags = allInputs.concat(allSelects);不起作用.

var allInputs = document.getElementsByTagName("input");
alert("Inputs: " + allInputs.length);

var allSelects = document.getElementsByTagName("select");
alert("Selects: " + allSelects.length);

var allTags = allInputs.concat(allSelects);
alert("allTags: " + allTags.length);
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 20

Concat适用于普通的数字和字符串数组,但不适用于对象数组.

实际上,确实如此,但是NodeList实例没有concat方法,Array#concat也没有办法确定你想要展平那些(因为它们不是数组).

但它仍然相当容易(尽管下面见警告).改变这一行:

var allTags = allInputs.concat(allSelects);
Run Code Online (Sandbox Code Playgroud)

var allTags = [];
allTags.push.apply(allTags, allInputs);
allTags.push.apply(allTags, allSelects);
Run Code Online (Sandbox Code Playgroud)

实例 | 资源

这通过使用一些技巧来工作: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;
}
Run Code Online (Sandbox Code Playgroud)

实例 | 资源

确实适用于IE8及更早版本(以及其他版本).