提问



我正在尝试编写一个接受字符串列表或单个字符串的函数。如果它是一个字符串,那么我想将它转换为只包含一个项目的数组。然后我可以循环它而不用担心错误。


那么我该如何检查变量是否是一个数组?





我已经完成了下面的各种解决方案,并创建了一个jsperf测试。[69]

最佳参考


在现代浏览器中,您可以做到


Array.isArray(obj)


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


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


# 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

其它参考1


ECMAScript标准中给出的用于查找Object类的方法是使用Object.prototype中的toString方法。


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
}





查看@ T.J的彻底治疗。克劳德的博客,发表在他的评论中。[71]


查看此基准以了解哪种方法表现更好:http://jsben.ch/#/QgYAV [73] [74]


从@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']

其它参考2


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


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


您也可以尝试使用instanceof运算符


v instanceof Array

其它参考3


jQuery还提供$.isArray()方法:[76]




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;
}

其它参考4


Array.isArray运行速度很快,但并不是所有版本的浏览器都支持它。
所以你可以为其他人做一个例外并使用通用方法:


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

其它参考5


想象一下,下面有这个数组:


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);

其它参考6


简单的功能来检查这个:


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

其它参考7


您可以尝试这种方法:http://web.archive.org/web/20100424091244/http://www.ajaxdr.com/code/javascript-version-of-phps-is_array-function/[77]


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

其它参考8


正如MDN在这里所说:[79]



  使用 Array.isArray Object.prototype.toString.call 来区分
  数组中的常规对象



喜欢这个:



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

  • Array.isArray(arr)


其它参考9


您可以检查变量的类型是否为数组;


var myArray=[];

if(myArray instanceof Array)
{
....
}

其它参考10


我会创建一个函数来测试你正在处理的对象的类型......




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



对于这个问题,只有一个解决方案


x instanceof Array


其中x是变量,如果x是数组,它将返回true,如果不是则返回false。

其它参考11


考虑到这些意见,我试图改进这个答案:


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


它摆脱了if/else,并解释了数组为null或未定义的可能性

其它参考12


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


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

其它参考13


我这样做的方式非常简单。适合我。有什么缺点吗?


Array.prototype.isArray = true;

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

其它参考14


我用两种替代方法更新了jsperf小提琴以及错误检查。[82]


事实证明,在对象和数组原型中定义常量值的方法比任何其他方法都快。这是一个有点令人惊讶的结果。




/* 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方法。
但如果你想减少思考,请看一下:http://underscorejs.org/#isArray [83]


_.isArray(object) 


如果object是Array,则返回true。


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

其它参考15


我见过的最好的解决方案是替换类型的跨浏览器。检查Angus Croll的解决方案。[84]


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 */};

其它参考16


这是我的懒惰方法:


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方法表现得更好。[85]


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

其它参考17


斯托扬·斯特凡诺夫(Stoyan Stefanov)的书籍JavaScript模型中有一个很好的例子,它假设处理所有可能的问题以及利用ECMAScript 5方法Array.isArray()。 [88]


所以这里是:


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


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

其它参考18


你可能是isArray方法,但我更愿意检查


Object.getPrototypeOf(yourvariable) === Array.prototype

其它参考19


如果可以传递给此函数的唯一两种值是字符串或字符串数​​组,请保持简单并使用typeof检查字符串的可能性:


function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}

其它参考20


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))

其它参考21


测试输入值是否为数组的简单函数如下:


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


这适用于跨浏览器和旧版浏览器。这是从T.J. Crowders博文[90]

其它参考22


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


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' ]


注:字符串将转换为具有单个元素而不是字符数组的数组。删除isString检查是否相反。


我在这里使用过Array.isArray,因为它最强大也最简单。[91]

其它参考23


检查对象是否为数组的最简单,最快捷的方法。


 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

其它参考24


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




var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It's an array");
}



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


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


请注意,没有完美的功能可以始终检测所有可能的组合。 了解工具的所有功能和限制比使用魔术工具更好。

其它参考25


你可以试试这个:


var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();

arr.constructor.prototype.hasOwnProperty('push') //true

obj.constructor.prototype.hasOwnProperty('push') // false