你如何检查一个variables是否是JavaScript中的数组?
我想检查一个variables是否是一个数组或JavaScript中的单个值。
我find了一个可能的解决scheme…
if (variable.constructor == Array)...
这是最好的办法吗?
有几种检查variables是否是数组的方法。 最好的解决办法就是你select的那个。
variable.constructor === Array
这是Chrome上最快的方法,最有可能是所有其他浏览器。 所有数组都是对象,所以检查构造函数属性是JavaScript引擎的一个快速过程。
如果您在查找对象属性是否为数组时遇到问题,则必须先检查属性是否存在。
variable.prop && variable.prop.constructor === Array
其他一些方法是:
variable instanceof Array
作为第一个例子,这个方法的运行速度约为1/3 。 如果你的代码非常漂亮,而且性能不是很好,那么它仍然非常稳定,看起来更干净。 请注意,检查数字不起作用,因为variable instanceof Number
总是返回false
。 更新: instanceof
现在以2/3的速度!
Array.isArray(variable)
最后一个在我看来是最丑的,而且是最慢的一个。 作为第一个例子,以约1/5的速度运行。 Array.prototype实际上是一个数组。 你可以阅读更多关于它在这里https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
所以还有一个更新
Object.prototype.toString.call(variable) === '[object Array]';
这个人是最慢的尝试检查一个数组。 不过,这是您寻找任何types的一站式商店。 但是,由于您正在寻找一个数组,只需使用上面最快的方法。
另外,我跑了一些testing: http : //jsperf.com/instanceof-array-vs-array-isarray/33所以有一些乐趣,并检查出来。
注意:由于jsperf.comclosures,@EscapeNetscape创build了另一个testing。 http://jsben.ch/#/QgYAV我想确保原始链接保持每当jsperf恢复联机。;
你也可以使用:
if (value instanceof Array) { alert('value is Array!'); } else { alert('Not an array'); }
这在我看来似乎是一个非常优雅的解决scheme,但是对于他自己来说。
编辑:
从ES5开始,现在还有:
Array.isArray(value);
但是,这将打破旧的浏览器,除非你使用polyfills(基本上… IE8或类似的)。
我注意到有人提到jQuery,但我不知道有一个isArray()
函数。 事实certificate,它是在1.3版本中添加的。
jQuery按照Peter的说法来实现它:
isArray: function( obj ) { return toString.call(obj) === "[object Array]"; },
已经对jQuery有了很大的信心(尤其是他们的跨浏览器兼容技术),我将升级到1.3版本并使用它们的function(假设升级不会导致太多问题),或者直接在我的码。
非常感谢您的build议。
有各种各样的怪癖的解决scheme。 本页面提供了一个很好的概述。 一个可能的解决scheme是
function isArray(o) { return Object.prototype.toString.call(o) === '[object Array]'; }
这是一个古老的问题,但有同样的问题,我发现了一个非常优雅的解决scheme,我想分享。
向Array添加原型使其非常简单
Array.prototype.isArray = true;
现在,如果你有一个对象,你想testing一下,看看它的数组是否只是检查新的属性
var box = doSomething(); if (box.isArray) { // do something }
isArray仅在其数组可用时可用
在现代浏览器(和一些传统的浏览器),你可以做
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)
。 如果你使用下划线,你可以使用_.isArray(obj)
如果你不需要检测在不同帧中创build的数组,你也可以使用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)
通过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提到的主要失败是无法正确确定在不同的上下文中创build的数组,例如window
。 如果这个页面不够完善的话,那么这个页面会有更复杂的版
我个人喜欢Peter的build议: https : Array.isArray()
对于ECMAScript 3.对于ECMAScript 5,使用Array.isArray()
)
然而,对post的评论表明,如果toString()
完全改变了,那么检查一个数组的方式将会失败。 如果你真的想要具体,并确保toString()
没有改变,并没有问题的对象类属性( [object Array]
是一个对象的类属性是一个数组),那么我build议做像这样的东西:
//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权威指南第六版7.10中,它说Array.isArray()
是使用ECMAScript 5中的Array.isArray()
实现的。另外请注意,如果您要担心toString()
如果你正在改变的实现,你也应该担心其他内置方法的改变。 为什么使用push()
? 有人可以改变它! 这样的做法很愚蠢。 上面的检查是为那些担心toString()
改变的人提供的解决scheme,但我相信检查是不必要的。
当我发布这个问题时,我使用的JQuery版本没有包含isArray
函数。 如果它有,我可能会只是用它相信实现是最好的浏览器独立的方式来执行此特定types检查。
由于JQuery现在提供这个function,我会一直使用它…
$.isArray(obj);
(从版本1.6.2开始)它仍然使用表单中string的比较来实现
toString.call(obj) === "[object Array]"
以为我会为那些可能已经在脚本中使用Underscore.js库的人添加另一个选项。 Underscore.js有一个isArray()函数(请参阅http://underscorejs.org/#isArray )。
_.isArray(object)
如果object是一个Array,则返回true。
如果你只处理EcmaScript 5及以上,那么你可以使用内build的Array.isArray
函数
例如,
Array.isArray([]) // true Array.isArray("foo") // false Array.isArray({}) // false
如果您正在使用Angular,则可以使用angular.isArray()函数
var myArray = []; angular.isArray(myArray); // returns true var myObj = {}; angular.isArray(myObj); //returns false
在Crockford的JavaScript Good Part中 ,有一个函数来检查给定的参数是否是一个数组:
var is_array = function (value) { return value && typeof value === 'object' && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length')); };
他解释说:
首先,我们问这个值是否真实。 我们这样做是为了拒绝null和其他falsy值。 其次,我们询问types值是否是“对象”。 这对于对象,数组和(奇怪的)null来说是正确的。 第三,我们问是否值的长度属性是一个数字。 对于数组来说,这通常是正确的,但通常不是对象。 第四,我们问这个值是否包含拼接方法。 对于所有的arrays来说,这也是一样的。 最后,我们问长度属性是否可枚举(将由for循环产生长度?)。 这对于所有的数组都是错误的。 这是我发现的数组最可靠的testing。 不幸的是,它太复杂了。
我正在使用这一行代码:
if (variable.push) { // variable is array, since AMAIK only arrays have push() method. }
代码来自miksago/Evan.js/blob/master/src/evan.html
var isArray = Array.isArray || function(obj) { return !!(obj && obj.concat && obj.unshift && !obj.callee);};
通用解决scheme如下:
Object.prototype.toString.call(obj)=='[object Array]'
从ECMAScript 5开始,一个正式的解决scheme是:
Array.isArray(arr)
此外,对于旧的JavaScript库,你可以find下面的解决scheme,虽然它不够准确:
var is_array = function (value) { return value && typeof value === 'object' && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length')); };
解决scheme来自http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript
对于那些代码高尔夫球来说,用最less的字符来进行一个不可靠的testing:
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]
从w3schools :
function isArray(myArray) { return myArray.constructor.toString().indexOf("Array") > -1; }
我喜欢Brian的回答:
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; } }
但你可以这样做:
return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
我已经创build了这个小小的代码,它可以返回真正的types。
我还不确定performance,但这是一个尝试正确识别types。
它的工作原理类似于现在的types。
var user = [1,2,3] typeOf(user); //[object Array]
它认为它可能需要一些微调,并考虑到事情,我还没有碰到或testing正确。 所以欢迎进一步的改进,无论是性能还是错误的重新移植。
我认为使用myObj.constructor ==对象和myArray.constructor ==数组是最好的方法。 它比使用toString()快了20倍。 如果使用自己的构造函数来扩展对象,并希望这些创build被视为“对象”,那么这不起作用,否则其方法会更快。 typeof与构造函数方法一样快,但typeof [] =='object'返回true,这通常是不可取的。 http://jsperf.com/constructor-vs-tostring
有一件事要注意的是,null.constructor会抛出一个错误,所以如果你可能正在检查空值,你将不得不首先做(testThing!== null){}
function isArray(x){ return ((x != null) && (typeof x.push != "undefined")); }
由于.length属性对于JavaScript中的数组是特殊的,因此可以简单地说
obj.length === +obj.length // true if obj is an array
Underscorejs和其他一些库使用这个简单而简单的技巧。
我刚刚想到的东西:
if (item.length) //This is an array else //not an array