如何检查对象是否是数组?
-
23-10-2019 - |
题
我正在尝试编写一个可以接受字符串列表或单个字符串的函数。如果是一个字符串,那么我想将其转换为只有一项的数组。然后,我可以循环循环,而不必担心错误。
那么如何检查变量是否为数组?
我已经汇总了下面的各种解决方案,并创建了一个 JSPERF测试.
解决方案
在现代浏览器中,您可以做
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)
如果您不需要检测不同帧创建的数组,则也可以使用 instanceof
obj instanceof Array
其他提示
ecmasixt标准中给出的方法找到对象类别的方法是使用 toString
方法 Object.prototype
.
if( Object.prototype.toString.call( someVar ) === '[object Array]' ) {
alert( 'Array!' );
}
或者您可以使用 typeof
测试是否是字符串:
if( typeof someVar === 'string' ) {
someVar = [ someVar ];
}
或者,如果您不关心性能,则可以做一个 concat
到一个新的空数组。
someVar = [].concat( someVar );
还有您可以直接查询的构造函数:
if (somevar.constructor.name == "Array") {
// do something
}
查看 彻底治疗 从 @TJ Crowder的 博客,如下面的评论中所述。
看看这个 基准 了解哪种方法的性能更好: http://jsben.ch/#/qgyav
从 @bharath 使用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']
我会首先检查您的实施是否支持 isArray
:
if (Array.isArray)
return Array.isArray(v);
您也可以尝试使用 instanceof
操作员
v instanceof Array
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>
这是所有方法中最快的(所有受支持的浏览器):
function isArray(obj){
return !!obj && obj.constructor === Array;
}
想象你有这个 阵列以下:
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.isArray(arr);
下划线和Lodash:
_.isArray(arr);
array.isarray工作很快,但是所有版本的浏览器都不支持。因此,您可以对他人例外并使用通用方法:
Utils = {};
Utils.isArray = ('isArray' in Array) ?
Array.isArray :
function (value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
简单的功能来检查以下内容:
function isArray(object)
{
if (object.constructor === Array) return true;
else return false;
}
正如MDN所说 在这里:
利用 array.isarray 或者 object.prototype.tostring.call 将常规对象与阵列区分开
像这样:
Object.prototype.toString.call(arr) === '[object Array]'
, , 或者Array.isArray(arr)
这个问题只有一行解决方案
x instanceof Array
其中x是变量,如果x为数组,则将返回true,如果不是x。
您可以检查变量的类型是否为数组;
var myArray=[];
if(myArray instanceof Array)
{
....
}
我会做一个函数来测试您要处理的对象的类型...
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
然后,您可以写一个简单的if语句...
if(whatAmI(myVar) === "Array"){
// do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
// do string stuff
}
我以一种非常简单的方式做到这一点。为我工作。有缺点吗?
Array.prototype.isArray = true;
a=[]; b={};
a.isArray // true
b.isArray // (undefined -> false)
这是我的尝试 这个答案 考虑到评论:
var isArray = myArray && myArray.constructor === Array;
它摆脱了if/else,并解释了阵列为null或未定义的可能性
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]";
};
我已经更新了 JSPERF小提琴 使用两种替代方法以及错误检查。
事实证明,定义“对象”和“数组”原型中常数值的方法比其他任何方法都快。这是一个令人惊讶的结果。
/* 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/>");
如果变量获得未定义的值,则这两种方法无效,但是如果您确定它们具有值,则它们确实有效。关于检查性能是否值是数组或单个值,第二种方法看起来像是有效的快速方法。它的速度比Chrome上的“实例”稍快,是Internet Explorer,Opera和Safari(在我的机器上)的第二好方法的两倍。
我知道,人们正在寻找某种原始的JavaScript方法。但是,如果您想少考虑,请在这里看看: http://underscorejs.org/#isarray
_.isArray(object)
如果对象是数组,则返回true。
(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
我看到的最好的解决方案是类型的跨浏览器替换。检查安格斯·克罗尔的解决方案 这里.
TL; DR版本在下面,但文章是对问题的很好的讨论,因此如果您有时间,则应阅读它。
Object.toType = function(obj) {
return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[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模式 哪个可以处理所有可能的问题以及使用ecmascript 5方法 array.isarray().
所以这里是:
if (typeof Array.isArray === "undefined") {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
}
顺便说一下,如果您使用的是jQuery,则可以使用它的方法 $ .ISARRAY()
最简单,最快的方法来检查对象是否是数组。
var arr = [];
arr.constructor.name ==='Array' //return true;
或者
arr.constructor ===Array //return true;
或者您可以制作实用程序功能:
function isArray(obj){ return obj && obj.constructor ===Array}
用法:
isArray(arr); //return true
如果您知道您的对象没有contat方法,则可以使用以下内容。
var arr = [];
if (typeof arr.concat === 'function') {
console.log("It's an array");
}
您可以是IsArray方法,但我更喜欢检查
Object.getPrototypeOf(yourvariable) === Array.prototype
如果只有两种可以传递给此函数的值是字符串或一系列字符串,请保持简单并使用 typeof
检查字符串的可能性:
function someFunc(arg) {
var arr = (typeof arg == "string") ? [arg] : arg;
}
A = [1,2,3]
console.log(A.map==[].map)
在搜索最短版本时,这是我到目前为止得到的。
请注意,没有完美的功能可以始终检测到所有可能的组合。 比期望魔术工具了解工具的所有能力和局限性更好。
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))
一个简单的测试功能,如果输入值为数组,则如下:
function isArray(value)
{
return Object.prototype.toString.call(value) === '[object Array]';
}
这可以通过浏览器和较旧的浏览器进行操作。这是 从TJ人群博客文章中提取
您可以尝试一下:
var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();
arr.constructor.prototype.hasOwnProperty('push') //true
obj.constructor.prototype.hasOwnProperty('push') // false
此功能几乎将任何内容变成一个数组:
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]"
}
它使用一些较新的浏览器功能,因此您可能需要将其进行整理,以获得最大的支持。
例子:
> 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' ]
NB字符串将转换为具有单个元素而不是字符数组的数组。删除 isString
检查您是否希望相反。
我用过了 Array.isArray
在这里,因为这是 最健壮 也最简单。
在您的情况下,您可能会使用 concat
的方法 大批 可以接受单个对象以及数组(甚至组合):
function myFunc(stringOrArray)
{
var arr = [].concat(stringOrArray);
console.log(arr);
arr.forEach(function(item, i)
{
console.log(i, "=", item);
})
}
myFunc("one string");
myFunc(["one string", "second", "third"]);
concat
似乎是最古老的数组方法之一(即使是5.5也很了解)。