你是一个数组
JavaScript总会给我们带来一些惊喜。例如,typeof []它返回的是对象而不是数组。
不?是!哦!!!!
这有历史原因。但这可能会让人非常困惑。
那么,如何正确地检查某个对象是否为数组呢?
构造函数
例如,您可以检查构造函数是否为数组。
([]).constructor === Array // true
(new Array).constructor === Array // true
({}).constructor === Array // false
(true).constructor === Array // false
(null).constructor === Array // TypeError
(undefined).constructor === Array // TypeError
如您所见,这里存在问题。对于 null 和 undefined 值,会抛出 TypeError 异常。
例如,你可以使用 try/catch 语句来捕获这个问题。
try {
(undefined).constructor === Array // true
} catch(e) {
}
但你肯定不希望那样。
异国情调
还有一种比较特殊的用法,就是检查它是否为数组。你可能会滥用这个toString()方法。
Object.prototype.toString.call([]).indexOf('Array')!==-1
// => true
Object.prototype.toString.call({}).indexOf('Array')!==-1
// => false
Object.prototype.toString.call("").indexOf('Array')!==-1
// => false
Object.prototype.toString.call(null).indexOf('Array')!==-1
// => false
Object.prototype.toString.call(true).indexOf('Array')!==-1
// => false Object.prototype.toString.call(undefined).indexOf('Array')!==-1
// => false
但这不仅看起来很尴尬,实际上也很尴尬。
实例
当然,也可以使用其他语言中常见的 instanceof 运算符。
[] instanceof Array // => true
{} instanceof Array // => false
"" instanceof Array // => false
null instanceof Array // => false
true instanceof Array // => false
10 instanceof Array // => false
undefined instanceof Array // => false
看起来已经相当不错了。但这里也存在一个问题。
所有这些检查仅在数组是由当前环境中的原始数组构造函数创建时才有效。
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeArray = window.frames[window.frames.length-1].Array;
const array = new iframeArray(1,2,3);
这里两个数组实例不匹配。
array instanceof Array; // false
但确实有解决办法。
Array.isArray
基于这些原因,自 ECMAScript 5 起,存在一个方法Array.isArray()。
这同样适用于不同的实例。
Array.isArray([]) // => true
Array.isArray(Array.prototype) // => surprise; true
Array.isArray({}) // => false
Array.isArray("") // => false
Array.isArray(null) // => false
Array.isArray(true) // => false
Array.isArray(undefined) // => false
如果支持 isArray,那就是解决方案!
希望你喜欢!