正如我在该主题的研究中所发现的那样,您只有几个选择:
你只能看.length
属性并接受任何似乎具有适当属性的对象.length
属性不是您知道应该消除的任何其他东西(例如函数)。
您可以检查特定的类似数组的对象(HTMLCollection
, nodeList
)并偏向于他们。
第一种方法有两个选项 - 一个不接受零长度,一个接受零长度(这些包含 gilly3 的建议以及我们在 jQuery 类似函数中看到的内容):
// see if it looks and smells like an iterable object, but don't accept length === 0
function isArrayLike(item) {
return (
Array.isArray(item) ||
(!!item &&
typeof item === "object" &&
item.hasOwnProperty("length") &&
typeof item.length === "number" &&
item.length > 0 &&
(item.length - 1) in item
)
);
}
这当然是报道false
对于带有.length === 0
,如果你想允许.length === 0
,那么逻辑也可以包含该情况。
// see if it looks and smells like an iterable object, and do accept length === 0
function isArrayLike(item) {
return (
Array.isArray(item) ||
(!!item &&
typeof item === "object" &&
typeof (item.length) === "number" &&
(item.length === 0 ||
(item.length > 0 &&
(item.length - 1) in item)
)
)
);
}
一些测试用例:http://jsfiddle.net/jfriend00/3brjc/ http://jsfiddle.net/jfriend00/3brjc/
2)检查它不是一个实际的数组后,您可以编写代码来检查特定类型的类似数组的对象(例如nodeList
, HTMLCollection
).
例如,当我想确保包含 nodeList 和 HTMLCollection 类似数组的对象时,我使用以下方法:
// assumes Array.isArray or a polyfill is available
function canAccessAsArray(item) {
if (Array.isArray(item)) {
return true;
}
// modern browser such as IE9 / firefox / chrome etc.
var result = Object.prototype.toString.call(item);
if (result === "[object HTMLCollection]" || result === "[object NodeList]") {
return true;
}
//ie 6/7/8
if (typeof item !== "object" || !item.hasOwnProperty("length") || item.length < 0) {
return false;
}
// a false positive on an empty pseudo-array is OK because there won't be anything
// to iterate so we allow anything with .length === 0 to pass the test
if (item.length === 0) {
return true;
} else if (item[0] && item[0].nodeType) {
return true;
}
return false;
}