如何在JavaScript中检查变量是否为数组?
if (variable.constructor == Array)
如何在JavaScript中检查变量是否为数组?
if (variable.constructor == Array)
当前回答
这是一个老问题,但有同样的问题,我找到了一个非常优雅的解决方案,我想分享。
将原型添加到Array使其非常简单
Array.prototype.isArray = true;
现在,如果您有一个要测试的对象,看看它是否是一个数组,您只需要检查新属性
var box = doSomething();
if (box.isArray) {
// do something
}
isArray仅在其为数组时可用
其他回答
在Crockford的JavaScript The Good Parts中,有一个函数可以检查给定的参数是否为数组:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
他解释道:
首先,我们问这个价值是否真实。我们这样做是为了拒绝空值和其他错误值。第二,我们询问值的类型是否为“object”。这对于对象、数组和(奇怪的)null都是正确的。第三,我们询问该值是否具有数字的长度属性。对于数组总是如此,但对于对象通常不是如此。第四,我们询问该值是否包含拼接方法。这同样适用于所有阵列。最后,我们问长度属性是否可枚举(长度是否由for in循环产生?)。这对于所有数组都是错误的。这是我发现的最可靠的阵列测试。不幸的是,它如此复杂。
对于那些编码高尔夫的人来说,这是一个字符最少的不可靠测试:
function isArray(a) {
return a.map;
}
这通常在遍历/展平层次结构时使用:
function golf(a) {
return a.map?[].concat.apply([],a.map(golf)):a;
}
input: [1,2,[3,4,[5],6],[7,[8,[9]]]]
output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
我个人喜欢彼得的建议:https://stackoverflow.com/a/767499/414784(对于ECMAScript 3。对于ECMAScript 5,请使用Array.isArray())
然而,帖子上的评论表明,如果toString()被更改,那么检查数组的方法将失败。如果您真的想具体一些,并确保toString()没有更改,并且objects类属性([objectArray]是数组对象的类属性)没有问题,那么我建议您这样做:
//see if toString returns proper class attributes of objects that are arrays
//returns -1 if it fails test
//returns true if it passes test and it's an array
//returns false if it passes test and it's not an array
function is_array(o)
{
// make sure an array has a class attribute of [object Array]
var check_class = Object.prototype.toString.call([]);
if(check_class === '[object Array]')
{
// test passed, now check
return Object.prototype.toString.call(o) === '[object Array]';
}
else
{
// may want to change return value to something more desirable
return -1;
}
}
注意,在JavaScript《最终指南》第6版7.10中,它说Array.isArray()是使用ECMAScript 5中的Object.pr原型.toString.call()实现的。还要注意,如果您要担心toString()的实现发生变化,那么您也应该担心其他内置方法也会发生变化。为什么使用push()?有人可以改变它!这种做法很愚蠢。上面的检查是为那些担心toString()更改的人提供的解决方案,但我认为检查是不必要的。
在现代浏览器(以及一些传统浏览器)中,您可以
Array.isArray(obj)
(支持Chrome 5、Firefox 4.0、IE 9、Opera 10.5和Safari 5)
如果需要支持旧版本的IE,可以使用es5垫片来polyfill Array.isArray;或添加以下内容
# only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
};
如果使用jQuery,可以使用jQuery.isArray(obj)或$.isArra(obj
如果不需要检测在不同帧中创建的数组,也可以只使用instanceof
obj instanceof Array
注意:可以用于访问函数参数的arguments关键字不是Array,尽管它(通常)的行为类似于:
var func=函数(){console.log(参数)//[1,2,3]console.log(arguments.length)//3console.log(Array.isArray(参数))//false!!!console.log(argument.slice)//未定义(Array.prototype方法不可用)console.log([3,4,5].slice)//函数slice(){[本机代码]}}函数(1,2,3)
我想我会为那些可能已经在脚本中使用Undercore.js库的人添加另一个选项。Undercore.js有一个isArray()函数(请参见http://underscorejs.org/#isArray).
_.isArray(object)
如果对象是数组,则返回true。