我有以下javascript代码:
var objectArray = [];
var allInputObjects = [];
var allSelectObjects = [];
var allTextAreaObjects = [];
//following returns 3 objects
allInputObjects = document.getElementById("divPage0").getElementsByTagName("INPUT");
//following returns 1 object
allSelectObjects = document.getElementById("divPage1").getElementsByTagName("SELECT");
//following returns 0 objects
allTextAreaObjects = document.getElementById("divPage2").getElementsByTagName("TEXTAREA");
//and following statement does not work
objectArray = allInputObjects.concat(allSelectObjects);
我的问题是最后一行是抛出错误。
我在Firefox中尝试了上述代码,它说allInputObjects.concat
不是函数。
任何线索,我相信脚本不会将allInputObjects视为数组!
任何帮助将不胜感激。
答案 0 :(得分:4)
为什么您认为allSelectObjects
是一个数组?
它最初被分配给一个空数组,当然。但是它被第6行(ish)上的getElementsByTagName
调用覆盖了。 Javascript中的变量不是强类型的,因此初始赋值不会强制以后的赋值也是数组。
我怀疑当你调用最后一行时,你会在变量中有某种类型的NodeList
或类似的,而不是数组。 (这至少是Firefox中的returned by the method。)
答案 1 :(得分:4)
getElementsByTagName
返回NodeList
,类似于Array
,但它不支持所有原型函数。
要将类似数组的对象无缝转换为数组,请使用:
var arr = Array.prototype.slice.call(somenodelist, 0);
arr
几乎完全相同,只是它现在支持Array
原型函数,例如concat
。
该函数实际上做的是返回包含Array
元素的部分somenodelist
,准确地说是索引0和之后的所有内容。显然,这只是所有元素,因此这是将类似数组的对象转换为真实Array
的技巧。
答案 2 :(得分:3)
正如Andezej指出的那样,你在这里没有处理数组,你正在处理一种节点列表。
根据getElementsByTagName
var tags = obj.getElementsByTagName('input');
for (var j=0;j<tags.length;j++) {
resultArray.push(tags[j]);
}
答案 3 :(得分:1)
将NodeList
转换为数组的另一种有趣方式:
var tags = obj.getElementsByTagName('input'),
tags2Arr = (
function toArr(i){
return i ? toArr(i-1).concat(tags[i]) : [tags[0]];
}(tags.length-1)
);
现在,如果您向Array.prototype
添加方法:
Array.prototype.clone = function() {
var arr = this;
return (function clone(i){
return i ? clone(i-1).concat(arr[i]) : [arr[0]];
})(this.length-1);
};
您可以使用此oneliner将NodeList
转换为数组:
Array.prototype.clone.call(obj.getElementsByTagName('input'));