如何在JavaScript中检查一个变量是否为数组?
if (variable.constructor == Array)
如何在JavaScript中检查一个变量是否为数组?
if (variable.constructor == Array)
有几种方法可以检查一个变量是否为数组。最好的解决方案是您选择的那个。
variable.constructor === Array
这是Chrome最快的方法,很可能在其他浏览器中也是如此。所有数组都是对象,因此检查构造函数属性对于JavaScript引擎来说是一种快速的过程。
如果您在查找对象属性是否为数组方面遇到问题,则必须首先检查该属性是否存在。
variable.prop && variable.prop.constructor === Array
其他一些方法包括:
Array.isArray(variable)
2019年5月23日更新,使用Chrome 75,感谢@AnduAndrici提出的问题让我重新审视这个问题。 在我看来,最后一个例子是最丑陋的,但也是最快的。虽然速度比第一个例子慢了大约2-5%,但很难分辨。非常实用!结果令人印象深刻。Array.prototype实际上是一个数组,您可以在此处https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray上阅读更多信息。
variable instanceof Array
这种方法的运行速度大约是第一个示例的 1/3。仍然相当可靠,看起来更清晰,如果您关注优美的代码而不是性能。注意,检查数字不起作用,因为 variable instanceof Number
总是返回 false
。更新:现在 instanceof
的速度提高了 2/3!
所以又有了更新。
Object.prototype.toString.call(variable) === '[object Array]';
这个方法检测数组的速度最慢,但是它可以处理你需要的任何类型。不过,既然你要查找的是数组,那么就使用上面最快的方法吧。
另外,我进行了一些测试:http://jsperf.com/instanceof-array-vs-array-isarray/35,所以来试试吧。
注意:由于 jsperf.com 当前无法访问,@EscapeNetscape 创建了另一个测试 http://jsben.ch/#/QgYAV。我希望原始链接能在 jsperf 恢复时保留下来。
你也可以使用:
if (value instanceof Array) {
alert('value is Array!');
} else {
alert('Not an array');
}
这对我来说是一个相当优雅的解决方案,但各有所好。
编辑:
从ES5开始,现在也有:
Array.isArray(value);
但是在老的浏览器上,这将会出现问题,除非你使用了polyfill(基本上是...IE8或类似的浏览器)。
Array instanceof Object == true
。 - Pierre在现代浏览器(和一些传统浏览器)中,您可以执行以下操作:
Array.isArray(obj)
(浏览器支持情况:Chrome 5、Firefox 4.0、IE 9、Opera 10.5 和 Safari 5)
如果你需要支持旧版本的 IE,你可以使用es5-shim 来填充 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)
或$.isArray(obj)
。如果您使用underscore,则可以使用_.isArray(obj)
。如果您不需要检测在不同框架中创建的数组,也可以使用instanceof
。obj instanceof Array
注意:可以用于访问函数参数的 arguments
关键字并非数组,尽管它(通常)表现得像一个数组:
var func = function() {
console.log(arguments) // [1, 2, 3]
console.log(arguments.length) // 3
console.log(Array.isArray(arguments)) // false !!!
console.log(arguments.slice) // undefined (Array.prototype methods not available)
console.log([3,4,5].slice) // function slice() { [native code] }
}
func(1, 2, 3)
prototype
吗?看起来应该是 Object.prototype.toString.call
。 - Brock有多种解决方案,每个方案都有其特殊之处。这个页面提供了一个很好的概述。其中一种可能的解决方案是:
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
isArray()
函数。结果发现它是在1.3版本中添加的。isArray: function( obj ) {
return toString.call(obj) === "[object Array]";
},
已经对jQuery充满信心(特别是它们用于跨浏览器兼容性的技术),如果升级不会导致太多问题,我将升级到1.3版本并使用他们的函数,或者直接在我的代码中使用此建议方法。
非常感谢您的建议。
这是一个老问题,但我找到了一个非常优美的解决方案,想要分享。
在数组中添加一个原型会使它变得非常简单。
Array.prototype.isArray = true;
如果你想测试一个对象是否为数组,现在只需检查新属性即可。
var box = doSomething();
if (box.isArray) {
// do something
}
如果它是一个数组,那么isArray才可用。
Object.prototype.isArray = true;
!:( - ErikEArray.isArray
是一个方法(例如 Array.isArray([1,2,3]) === true
),所以 @ErikE 并不是在恶意挑衅。我建议避免使用这个回答,因为它会在某些现代浏览器中破坏代码。 - JaredMcAteer{}.isArray === true
,这正是我的初衷... - ErikE根据 Crockford 的说法:
function typeOf(value) {
var s = typeof value;
if (s === 'object') {
if (value) {
if (value instanceof Array) {
s = 'array';
}
} else {
s = 'null';
}
}
return s;
}
Crockford提到的主要问题是无法正确确定在不同上下文中创建的数组,例如window
。
如果这不足以解决问题,该页面还有一个更复杂的版本。Array.isArray
函数。Array.isArray([]) // true
Array.isArray("foo") // false
Array.isArray({}) // false
我个人喜欢Peter的建议:https://dev59.com/K3RA5IYBdhLWcg3w9izq#767499(适用于ECMAScript 3。对于ECMAScript 5,请使用Array.isArray()
)
然而,帖子上的评论表明,如果toString()
被更改了,那种检查数组的方式将会失败。如果你想要更加具体并确保toString()
没有被更改,并且对象的类属性没有问题([object Array]
是一个数组对象的类属性),那么我建议像这样做:
//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.prototype.toString.call()
实现的。还要注意,如果你担心toString()
的实现发生变化,你也应该担心其他所有内置方法的变化。为什么要使用push()
?有人可能会对其进行更改!这种方法很愚蠢。上述检查是提供给那些担心toString()
变化的解决方案,但我认为这个检查是不必要的。return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
- Grant Lindsay当我发布这个问题时,我使用的JQuery版本不包括isArray
函数。如果有的话,我可能会直接使用它,并相信这种实现方法是执行特定类型检查的最佳浏览器无关方式。
既然JQuery现在提供了这个函数,我会始终使用它...
$.isArray(obj);
(截至版本1.6.2)此仍然是使用字符串比较实现的形式
toString.call(obj) === "[object Array]"