检查对象是否是数组?

我试图写一个函数,接受一个string的列表,或单个string。 如果它是一个string,那么我想将它转换为只有一个项目的数组。 然后我可以循环而不用担心错误。

那么如何检查variables是否是一个数组呢?


我已经围绕下面的各种解决scheme,并创build了一个jsperftesting 。

我会首先检查你的实现是否支持isArray

 if (Array.isArray) return Array.isArray(v); 

你也可以尝试使用instanceof操作符

 v instanceof Array 

在ECMAScript标准中给出的findObject类的方法是使用Object.prototypetoString方法。

 if( Object.prototype.toString.call( someVar ) === '[object Array]' ) { alert( 'Array!' ); } 

或者你可以使用typeof来testing它是否是一个string:

 if( typeof someVar === 'string' ) { someVar = [ someVar ]; } 

或者如果你不关心性能,你可以做一个concat到一个新的空数组。

 someVar = [].concat( someVar ); 

还有你可以直接查询的构造函数:

 if (somevar.constructor.name == "Array") { // do something } 

编辑:从@TJ Crowder的博客中查看一下彻底的治疗 ,正如他在下面的评论中所发表的。

编辑2:看看这个基准得到一个想法哪个方法执行更好: http : //jsben.ch/#/QgYAV

编辑3:从@Bharath将string转换为使用Es6的数组问题:

 const convertStringToArray = (object) => { return (typeof object === 'string') ? Array(object) : object } 

假设:

 let m = 'bla' let n = ['bla','Meow'] let y = convertStringToArray(m) let z = convertStringToArray(n) console.log('check y: '+JSON.stringify(y)) . // check y: ['bla'] console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow'] 

jQuery还提供了一个$.isArray()方法:

 var a = ["A", "AA", "AAA"]; if($.isArray(a)) { alert("a is an array!"); } else { alert("a is not an array!"); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

在现代浏览器中,你可以做

 Array.isArray(obj) 

( 由 Chrome 5,Firefox 4.0,IE 9,Opera 10.5和Safari 5支持)

为了向后兼容,您可以添加以下内容

 # 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 

这是所有方法(支持所有浏览器)中最快的:

 function isArray(obj){ return !!obj && obj.constructor === Array; } 

Array.isArray工作得很快,但并不是所有版本的浏览器都支持。 所以你可以为他人制定一个例外的规定,并使用通用的方法

  Utils = {}; Utils.isArray = ('isArray' in Array) ? Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } 

简单的function来检查这一点:

 function isArray(object) { if (object.constructor === Array) return true; else return false; } 

想象下面你有这个数组:

 var arr = [1,2,3,4,5]; 

Javascript(新旧浏览器):

 function isArray(arr) { return arr.constructor.toString().indexOf("Array") > -1; } 

要么

 function isArray(arr) { return arr instanceof Array; } 

要么

 function isArray(arr) { return Object.prototype.toString.call(arr) === '[object Array]'; } 

然后像这样调用它:

 isArray(arr); 

Javascript(IE9 +,Ch5 +,FF4 +,Saf5 +,Opera10.5 +)

 Array.isArray(arr); 

jQuery的:

 $.isArray(arr); 

angular度:

 angular.isArray(arr); 

下划线和Lodash:

 _.isArray(arr); 

你可以试试这个方法: http : //web.archive.org/web/20100424091244/http : //www.ajaxdr.com/code/javascript-version-of-phps-is_array-function/

编辑 :另外,如果你已经在你的项目中使用JQuery,你可以使用它的函数$ .isArray() 。

正如MDN 在这里所说:

使用Array.isArrayObject.prototype.toString.call来区分常规对象和数组

喜欢这个:

  • Object.prototype.toString.call(arr) === '[object Array]' ,或者

  • Array.isArray(arr)

你可以检查你的variables的types是否是一个数组;

 var myArray=[]; if(myArray instanceof Array) { .... } 

我会做一个函数来testing你正在处理的对象的types…

 function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; } // tests console.log( whatAmI(["aiming","@"]), whatAmI({living:4,breathing:4}), whatAmI(function(ing){ return ing+" to the global window" }), whatAmI("going to do with you?") ); // output: Array Object Function String 

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray

 Array.isArray = Array.isArray || function (vArg) { return Object.prototype.toString.call(vArg) === "[object Array]"; }; 

我以一个非常简单的方式做到这一点。 为我工作。 有什么缺点?

 Array.prototype.isArray = true; a=[]; b={}; a.isArray // true b.isArray // (undefined -> false) 

这是我试图改进这个答案考虑到的意见:

 var isArray = myArray && myArray.constructor === Array; 

它摆脱了if / else,并说明数组为空或未定义的可能性

这个问题只有一个线路解决scheme

 x instanceof Array 

其中x是variables,如果x是数组,则返回true,否则返回false。

我已经更新了两个替代方法,以及错误检查jsperf小提琴 。

事实certificate,在“Object”和“Array”原型中定义一个常数值的方法比任何其他方法都快。 这是一个有点令人惊讶的结果。

 /* Initialisation */ Object.prototype.isArray = function() { return false; }; Array.prototype.isArray = function() { return true; }; Object.prototype._isArray = false; Array.prototype._isArray = true; var arr = ["1", "2"]; var noarr = "1"; /* Method 1 (function) */ if (arr.isArray()) document.write("arr is an array according to function<br/>"); if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>"); /* Method 2 (value) - **** FASTEST ***** */ if (arr._isArray) document.write("arr is an array according to member value<br/>"); if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>"); 

我知道,人们正在寻找某种原始的JavaScript方法。 但是,如果你想less想一点,看看这里: http : //underscorejs.org/#isArray

 _.isArray(object) 

如果object是一个Array,则返回true。

 (function(){ return _.isArray(arguments); })(); => false _.isArray([1,2,3]); => true 

我见过的最好的解决scheme是typeof的跨浏览器替代。 在这里查看Angus Croll的解决scheme。

TL,DR版本在下面,但文章是关于这个问题的一个很好的讨论,所以你应该阅读它,如果你有时间的话。

 Object.toType = function(obj) { return ({}).toString.call(obj).match(/\s([az|AZ]+)/)[1].toLowerCase(); } // ... and usage: Object.toType([1,2,3]); //"array" (all browsers) // or to test... var shouldBeAnArray = [1,2,3]; if(Object.toType(shouldBeAnArray) === 'array'){/* do stuff */}; 

这是我懒惰的做法:

 if (Array.prototype.array_ === undefined) { Array.prototype.array_ = true; } // ... var test = [], wat = {}; console.log(test.array_ === true); // true console.log(wat.array_ === true); // false 

我知道这是“亵渎”原型的亵渎,但它似乎比推荐的toString方法更好地执行 。

注意:这种方法的一个缺陷是,它不会跨iframe边界工作 ,但对于我的用例,这不是一个问题。

在Stoyan Stefanov的书JavaScript Patterns中有一个很好的例子,它假定处理所有可能的问题,并且使用ECMAScript 5方法Array.isArray() 。

所以这里是:

 if (typeof Array.isArray === "undefined") { Array.isArray = function (arg) { return Object.prototype.toString.call(arg) === "[object Array]"; }; } 

顺便说一句,如果你使用jQuery,你可以使用它的方法$ .isArray()

如果可以传递给这个函数的唯一两种值是一个string或一个string数组,那么保持简单,并使用string可能性的types检查:

 function someFunc(arg) { var arr = (typeof arg == "string") ? [arg] : arg; } 
 function isArray(value) { if (value) { if (typeof value === 'object') { return (Object.prototype.toString.call(value) == '[object Array]') } } return false; } var ar = ["ff","tt"] alert(isArray(ar)) 

testinginput值是否是数组的简单函数如下:

 function isArray(value) { return Object.prototype.toString.call(value) === '[object Array]'; } 

这适用于跨浏览器和旧浏览器。 这是从TJ Crowders的博客文章中提取的

 A = [1,2,3] console.log(A.map==[].map) 

寻找最短的版本,这是我到目前为止。

请注意,没有完美的function,将始终检测所有可能的组合。 知道你的工具的所有能力和局限性比期望一个神奇的工具更好。

这个函数几乎可以把任何东西变成一个数组:

 function arr(x) { if(x === null || x === undefined) { return []; } if(Array.isArray(x)) { return x; } if(isString(x) || isNumber(x)) { return [x]; } if(x[Symbol.iterator] !== undefined || x.length !== undefined) { return Array.from(x); } return [x]; } function isString(x) { return Object.prototype.toString.call(x) === "[object String]" } function isNumber(x) { return Object.prototype.toString.call(x) === "[object Number]" } 

它使用了一些较新的浏览器function,所以你可能想要填充这个最大的支持。

例子:

 > arr(null); [] > arr(undefined) [] > arr(3.14) [ 3.14 ] > arr(1/0) [ Infinity ] > gen = function*() { yield 1; yield 2; yield 3; } [Function: gen] > arr(gen()) [ 1, 2, 3 ] > arr([4,5,6]) [ 4, 5, 6 ] > arr("foo") [ 'foo' ] 

NBstring将被转换成一个数组,而不是一个字符数组。 删除isString检查,如果你更喜欢isString

我在这里使用了Array.isArray ,因为它是最健壮和最简单的。

最简单和最快速的方法来检查一个对象是否是一个数组。

  var arr = []; arr.constructor.name ==='Array' //return true; 

要么

 arr.constructor ===Array //return true; 

或者你可以做一个实用的function:

 function isArray(obj){ return obj && obj.constructor ===Array} 

用法:

 isArray(arr); //return true 

如果你知道你的对象没有concat方法,可以使用下面的代码。

 var arr = []; if (typeof arr.concat === 'function') { console.log("It's an array"); } 
 var is_array = function (value) { return value && typeof value === 'object' && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length')); }; 

这个function取自“JS优秀部分”一书,对我来说很完美。

你可以试试这个:

 var arr = []; (or) arr = new Array(); var obj = {}; (or) arr = new Object(); arr.constructor.prototype.hasOwnProperty('push') //true obj.constructor.prototype.hasOwnProperty('push') // false