检查对象是否是数组?
我试图写一个函数,接受一个string的列表,或单个string。 如果它是一个string,那么我想将它转换为只有一个项目的数组。 然后我可以循环而不用担心错误。
那么如何检查variables是否是一个数组呢?
我已经围绕下面的各种解决scheme,并创build了一个jsperftesting 。
我会首先检查你的实现是否支持isArray
:
if (Array.isArray) return Array.isArray(v);
你也可以尝试使用instanceof
操作符
v instanceof Array
在ECMAScript标准中给出的findObject类的方法是使用Object.prototype
的toString
方法。
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.isArray或Object.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