如何在 JavaScript 中检查变量是否为数组?

How do I check if a variable is an array in JavaScript?

提问人:Andy McCluggage 提问时间:4/20/2009 最后编辑:Mateen UlhaqAndy McCluggage 更新时间:11/9/2023 访问量:1218840

问:

如何在 JavaScript 中检查变量是否为数组?

if (variable.constructor == Array)
JavaScript 数组列表 变量

评论

3赞 aleemb 4/20/2009
检查一个对象是否是一个数组有一些特定的警告......彼得的答案是你唯一应该使用的答案。
1赞 Peter Smit 8/8/2011
@Andy看来我的答案不是最好的。也许你应该选择一个不同的答案作为接受的答案?
2赞 Andy McCluggage 8/8/2011
彼得说得好。我没有意识到你的回答正在收到这样的评论。我想我早就开始在检查数组时使用 JQuery.isArray 函数,有趣的是,它的实现方式与此处给出的任何其他答案不同。我已将流行的答案标记为正确。
1赞 Andy McCluggage 8/8/2011
对不起,这是错误的。我看得更深一点,(从版本 1.6.2 开始)JQuery 仍然使用表单中的比较进行类型检查......toString.call(obj) === “[对象数组]”
8赞 Dexygen 11/12/2017
“这个问题以前有人问过”......不,这个问题是在这个问题之后被问到的

答:

1169赞 Brett Bender 4/20/2009 #1

您还可以使用:

if (value instanceof Array) {
  alert('value is Array!');
} else {
  alert('Not an array');
}

在我看来,这似乎是一个非常优雅的解决方案,但对每个人来说都是他自己的。

编辑:

从 ES5 开始,现在还有:

Array.isArray(value);

但这在较旧的浏览器上会中断,除非您使用的是 polyfills(基本上......IE8 或类似版本)。

评论

27赞 BYK 4/20/2009
我建议,如果您不使用多个帧,实际上坚持使用这个“instanceof”运算符。这是检查对象类型的正确方法。
45赞 Pierre 11/29/2012
此操作失败的一种情况是,如果您尝试测试数组或对象,因为 .Array instanceof Object == true
1赞 tuck 5/1/2013
如果您使用 jQuery 传递带有 find('code') 或类似内容的元素,则需要检查变量,因为它不是 Array 的实例。variable instanceof Object
5赞 Nobbynob Littlun 5/22/2014
@BrettBender 如果你仍然活跃,你能更新你的答案以反映从 ES5 开始我们有 Array.isArray 吗?
5赞 muffin 8/25/2014
@AndrewK请参阅 Fela Winkelmolen 的答案,该答案具有 Array.isArray 方法。至于这个答案,通过编辑将一个答案变成一个不同的答案可能不是一个好主意。
48赞 Hank Gay 4/20/2009 #2

通过克罗克福德

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (value instanceof Array) {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

Crockford 提到的主要失败是无法正确确定在不同上下文中创建的数组,例如 . 如果这还不够,该页面有一个更复杂的版本。window

82赞 Peter Smit 4/20/2009 #3

有多种解决方案各有各的怪癖。本页提供了一个很好的概述。一种可能的解决方案是:

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

评论

0赞 BYK 4/20/2009
如果您仔细阅读,它会说当您使用多框架文档时需要此方法,不建议这样做。这种方法可以很容易地对“toString”函数进行一些更改。
4赞 Peter Smit 4/20/2009
因此,给出了链接,以便 Brett 可以检查它们并查看在哪种情况下他的函数必须起作用
1赞 Brian 6/30/2012
请看下面的回答。我推荐彼得·斯密特(Peter Smit)的方式。
6赞 Hank 5/28/2015
Mozilla推荐使用此方法。
76赞 Andy McCluggage 4/20/2009 #4

我注意到有人提到了jQuery,但我不知道有一个isArray()函数。事实证明,它是在 1.3 版中添加的。

jQuery按照Peter的建议实现它:

isArray: function( obj ) {
    return toString.call(obj) === "[object Array]";
},

我已经对jQuery充满信心(尤其是他们的跨浏览器兼容性技术),我将升级到1.3版本并使用他们的功能(前提是升级不会导致太多问题),或者直接在我的代码中使用这个建议的方法。

非常感谢您的建议。

评论

0赞 Nick G. 3/13/2014
有关该主题的良好讨论,请参阅本文。结论是使用此解决方案。
1赞 polm23 5/27/2014
这给了我IE10中的错误SCRIPT65535。
2赞 didxga 5/26/2011 #5

引用自 https://github.com/miksago/Evan.js/blob/master/src/evan.js 的代码

  var isArray = Array.isArray || function(obj) {
    return !!(obj && obj.concat && obj.unshift && !obj.callee);};

评论

0赞 Marco Demaio 2/18/2014
为什么你同时测试和 ,这还不够测试吗?concatunshiftunshift
0赞 Kris 4/24/2014
我们检查 Array 是否移动的方法越多,它可能真的是一个数组。其他对象可能同时具有或但不太可能同时具有两者。concatunshift
20赞 Andy McCluggage 8/8/2011 #6

当我发布这个问题时,我使用的 JQuery 版本不包含函数。如果有的话,我可能会使用它,相信该实现是执行此特定类型检查的最佳独立于浏览器的方式。isArray

由于 JQuery 现在确实提供了这个功能,所以我会一直使用它......

$.isArray(obj);

(自 1.6.2 版起)它仍然使用对表单中的字符串进行比较来实现

toString.call(obj) === "[object Array]"
55赞 Ibu 10/25/2011 #7

这是一个老问题,但遇到同样的问题,我找到了一个非常优雅的解决方案,我想分享。

将原型添加到 Array 使它变得非常简单

Array.prototype.isArray = true;

现在,一旦你有一个对象,你想测试它是否是一个数组,你只需要检查新属性

var box = doSomething();

if (box.isArray) {
    // do something
}

isArray 仅在其数组时可用

评论

5赞 Markus Bruckner 12/29/2011
@Vitimtk 原型充当实际对象的后备,因此即使相关数组已经存在,这也应该有效。当然,在处理源行之前,它是行不通的。
38赞 ErikE 9/30/2012
假设没有人这样做!:(Object.prototype.isArray = true;
14赞 JaredMcAteer 7/11/2013
请注意,在 ES5 中有一个方法(例如,),所以@ErikE不是巨魔。我会避免遵循这个答案,因为它会破坏某些现代浏览器中的代码。Array.isArrayArray.isArray([1,2,3]) === true
4赞 ErikE 7/12/2013
@Ibu,你可以用我的“解决方案”来做,这就是重点......{}.isArray === true
2赞 BentOnCoding 9/24/2014
在我看来,修改数据类型的原型是一种不好的做法
30赞 Brian 12/3/2011 #8

我个人喜欢 Peter 的建议:https://stackoverflow.com/a/767499/414784(对于 ECMAScript 3。对于 ECMAScript 5,请使用Array.isArray())

然而,对帖子的评论表明,如果改变,检查数组的方式将失败。如果你真的想具体一点,并确保没有被改变,并且对象类属性(是数组对象的类属性)没有问题,那么我建议做这样的事情:toString()toString()[object Array]

//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 权威指南第 6 版,7.10 中,它说是使用 ECMAScript 5 实现的。另请注意,如果您要担心实现的更改,您还应该担心其他所有内置方法的更改。为什么使用?有人可以改变它!这种做法是愚蠢的。上述检查是为那些担心改变的人提供的解决方案,但我认为检查是不必要的。Array.isArray()Object.prototype.toString.call()toString()push()toString()

评论

1赞 styfle 12/14/2012
很好地调用了 ECMAScript 5 标准。当然,你不能保证浏览器支持它,但这应该是签入新代码的第一种方法。
0赞 Grant Lindsay 6/24/2014
我首先要说的是,这有点超出了我的脑海。但是,像这样的测试会更强大吗?return Object.prototype.toString.call(o) === Object.prototype.toString.call([]);
16赞 Benjen 3/16/2012 #9

以为我会为那些可能已经在脚本中使用 Underscore.js 库的人添加另一个选项。Underscore.js 有一个 isArray() 函数(参见 http://underscorejs.org/#isArray)。

_.isArray(object) 

如果 object 是 Array,则返回 true。

评论

1赞 Kris 4/24/2014
下划线 js 实现使用本机(如果可用),否则使用该方法。Array.isArraytoString
1赞 Jundiaius 4/13/2016
Lodash 中也存在相同的功能
1赞 Saeed Neamati 1/6/2013 #10

我使用的是这行代码:

if (variable.push) {
   // variable is array, since AMAIK only arrays have push() method.
}

评论

8赞 teleclimber 4/29/2014
这根本不是一个好的解决方案。有了这个“解决方案”,任何具有真实属性的对象都将被视为 Array。push
0赞 zeageorge 4/21/2013 #11

我喜欢布莱恩的回答:

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([]);
35赞 JaredMcAteer 7/11/2013 #12

如果您只处理 EcmaScript 5 及更高版本,则可以使用内置函数Array.isArray

例如,

Array.isArray([])    // true
Array.isArray("foo") // false
Array.isArray({})    // false
3赞 000 10/25/2013 #13

对于那些编写高尔夫代码的人来说,一个字符最少的不可靠测试:

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]
9赞 Yunzhou 12/3/2013 #14

在 Crockford 的 JavaScript The Good Parts 中,有一个函数可以检查给定的参数是否为数组:

var is_array = function (value) {
    return value &&
        typeof value === 'object' &&
        typeof value.length === 'number' &&
        typeof value.splice === 'function' &&
        !(value.propertyIsEnumerable('length'));
};

他解释道:

首先,我们询问该值是否真实。我们这样做是为了拒绝 null 和其他虚假值。其次,我们询问值的类型是否为“对象”。对于对象、数组和(奇怪的)null 都是如此。第三,我们询问该值是否具有一个数字的 length 属性。对于数组,这始终是正确的,但对于对象通常不是这样。第四,我们询问该值是否包含拼接方法。这同样适用于所有数组。最后,我们询问 length 属性是否可枚举(长度会由 for 循环生成吗?对于所有数组,这都是错误的。这是我发现的最可靠的阵列性测试。不幸的是,它是如此复杂。

评论

5赞 FrancescoMM 1/30/2017
而这只是好的部分。想象一下,当“JavaScript The Bad Parts”发布时......
86赞 Fela 1/8/2014 #15

在现代浏览器(以及一些传统浏览器)中,您可以执行以下操作

Array.isArray(obj)

(基金资助Chrome 5、Firefox 4.0、IE 9、Opera 10.5 和 Safari 5)

如果需要支持旧版本的 IE,可以使用 es5-shim 对 Array.isArray 进行 polyfill;或添加以下内容

# 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

注意:可用于访问函数参数的关键字不是 Array,即使它(通常)的行为类似于 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)

评论

3赞 John 4/12/2014
这可能是最好、最现代的方法。我已经在 MDN 上看到了它与 polyfill 一起,所以这意味着 Mozilla 信任它 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/......
0赞 Brock 11/20/2014
你没有错过那里吗?似乎应该是.prototypeObject.prototype.toString.call
0赞 aj go 6/13/2022
我们还可以确定对象是否具有数组中存在的方法,如 push、plice 等
-7赞 TypingTurtle 3/3/2014 #16

由于 .length 属性是 javascript 中数组的特殊属性,因此您可以简单地说

obj.length === +obj.length // true if obj is an array

Underscorejs 和其他几个库使用这个简短的技巧。

评论

1赞 Andy McCluggage 3/3/2014
你介意解释一下它是如何工作的吗?主要是,“+”有什么作用?
1赞 John 4/12/2014
这很好,但当对象是函数或字符串以及属性长度为 number 类型的任何其他对象时也是如此。为什么?好吧,一元 + 运算符实际上将变量转换为数字。所以基本上他们正在检查 obj.length 是否是一个数字。[object:Object] 没有属性长度,它是未定义的,因此当您将 undefined 转换为数字时,它将成为 NaN,上面的检查结果为 false。因此,如果对象属性长度为数字,则返回 true,对于数组、字符串和函数,它将返回 true。Underscore 必须做的不仅仅是这些。
10赞 joseph.l.hunsaker 3/19/2014 #17

如果您使用的是 Angular,则可以使用 angular.isArray() 函数

var myArray = [];
angular.isArray(myArray); // returns true

var myObj = {};
angular.isArray(myObj); //returns false

http://docs.angularjs.org/api/ng/function/angular.isArray

评论

1赞 PDA 7/18/2014
您也可以使用非 Angular 特定的浏览器,但只能使用 IE9+ 和所有标准浏览器:<pre><code> Array.isArray(myArray);返回 true Array.isArray(myObj);返回 false </code> </pre>
1赞 Val 7/28/2014 #18

我创建了一小段代码,它可以返回真正的类型。

我还不确定性能,但这是正确识别类型的尝试。

https://github.com/valtido/better-typeOf 也在这里写了一些关于它的博客 http://www.jqui.net/jquery/better-typeof-than-the-javascript-native-typeof/

它的工作原理类似于当前的 typeof。

var user = [1,2,3]
typeOf(user); //[object Array]

它认为它可能需要一些微调,并考虑到一些事情,我没有遇到或正确测试它。因此,欢迎进一步的改进,无论是性能方面,还是错误地重新移植 typeOf。

1赞 user1585789 8/25/2014 #19

我认为使用 myObj.constructor==Object 和 myArray.constructor==Array 是最好的方法。它比使用 toString() 快近 20 倍。如果您使用自己的构造函数扩展对象并希望这些创建也被视为“对象”,那么这是行不通的,但除此之外,它的速度更快。typeof 与构造函数方法一样快,但 typeof []=='object' 返回 true,这通常是不可取的。http://jsperf.com/constructor-vs-tostring

需要注意的一点是 null.constructor 会抛出一个错误,所以如果你可能正在检查 null 值,你必须先执行 if(testThing!==null){}

1987赞 jemiloii 10/29/2014 #20

有几种方法可以检查变量是否为数组。最好的解决方案是您选择的解决方案。

variable.constructor === Array

这是 Chrome 上最快的方法,很可能是所有其他浏览器。所有数组都是对象,因此检查构造函数属性对于 JavaScript 引擎来说是一个快速的过程。

如果在确定对象属性是否为数组时遇到问题,则必须首先检查该属性是否存在。

variable.prop && variable.prop.constructor === Array

其他一些方法有:

Array.isArray(variable)

2019 年 5 月 23 日使用 Chrome 75 更新,向 @AnduAndrici 大喊大叫,让我带着他的问题重新审视这个问题在我看来,最后一个是最丑陋的,也是最最快的之一。作为第一个示例,运行速度约为 1/5。这家伙慢了大约 2-5%,但很难说。使用起来很扎实!结果给我留下了深刻的印象。Array.prototype,实际上是一个数组。您可以在此处阅读有关它的更多信息 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray

variable instanceof Array

作为第一个示例,此方法的运行速度约为 1/3。仍然相当坚固,看起来更干净,如果你只关注漂亮的代码而不是性能。请注意,检查数字不会像往常一样返回 。更新:instanceof 现在的速度提高了 2/3!variable instanceof Numberfalse

所以又一次更新

Object.prototype.toString.call(variable) === '[object Array]';

这家伙是尝试检查数组最慢的。但是,这是您正在寻找的任何类型的一站式商店。但是,由于您正在寻找数组,因此只需使用上面最快的方法即可。

另外,我进行了一些测试: http://jsperf.com/instanceof-array-vs-array-isarray/35 所以玩得开心,看看吧。

注意:@EscapeNetscape已创建另一个测试,因为 jsperf.com 已关闭。http://jsben.ch/#/QgYAV我想确保每当 jsperf 重新上线时,原始链接都会保留。

评论

11赞 Michael Scott Asato Cuthbert 1/12/2015
请注意,如果您不确定变量是否已定义,或者它是否可能为 null,请务必先执行这些检查,因为这些是没有构造函数的常见值/对象。
7赞 GorvGoyl 10/5/2016
注意:如果变量为 null,则“variable.constructor === Array”将抛出 EXCEPTION,但“variable instanceof Array”不会!
6赞 Hedley Smith 10/10/2017
从 Chrome 59 开始,isArray() 似乎要快得多,以至于我认为没有理由在所有情况下都不使用 isArray()。
4赞 Bash 7/31/2019
@jemiloii我不同意清楚这一点。您的更新显示其运行速度是原始答案的 2/3。这是否意味着更快?慢?措辞有些含糊不清,尽管不可否认,该段落的上下文似乎表明速度较慢。我通过修改 jsben.ch/QgYAV 中的代码来运行一些自己的基准测试,但建议的这些结果是最快的。与此相关的是,jsben.ch/QgYAV 现在链接到一个空的基准测试。instanceofinstanceof
5赞 AtilioA 6/11/2020
如果您要编辑您的答案,请考虑让那些以前没有读过它的人更具可读性。
6赞 PixelsTech 1/11/2015 #21

通用解决方案如下:

Object.prototype.toString.call(obj)=='[object Array]'

从 ECMAScript 5 开始,一个正式的解决方案是:

Array.isArray(arr)

此外,对于旧的 JavaScript 库,您可以找到以下解决方案,尽管它不够准确:

var is_array = function (value) {
    return value &&
    typeof value === 'object' &&
    typeof value.length === 'number' &&
    typeof value.splice === 'function' &&
    !(value.propertyIsEnumerable('length'));
};

解决方案来自 http://www.pixelstech.net/topic/85-How-to-check-whether-an-object-is-an-array-or-not-in-JavaScript

-22赞 trololol 2/13/2015 #22

我刚刚想出的东西:

if (item.length) //This is an array else //not an array

评论

3赞 kev 3/6/2015
var item = 'this_is_not_an_array';
4赞 pmrotule 3/10/2015
这是一个糟糕的解决方案!字符串也有长度。
1赞 Shingala94 3/13/2015
实际上,字符串是一个字符数组,因此从本质上讲,这确实有效
6赞 wahwahwah 3/27/2015
@PatrickNijhuis - 字符串是 JavaScript 中的基元类型,而数组是一个对象。在通用语言中,你是正确的 - 字符串是一个字符数组 - 但在javascript中,这个断言是错误的。这是一个重要的区别,也是为什么这是一个糟糕的答案的原因。
3赞 Dave Burton 8/14/2016
不,零长度数组仍然是一个数组。
1赞 Jahid 3/29/2015 #23

来自 w3schools

function isArray(myArray) {
    return myArray.constructor.toString().indexOf("Array") > -1;
}
0赞 Ujjwal Raijada 6/2/2022 #24

我在这里尝试了大部分解决方案。但他们都没有奏效。然后我想出了一个简单的解决方案。希望它能帮助某人并节省他们的时间。

if(variable.constructor != undefined && variable.constructor.length > 0) {
        /// IT IS AN ARRAY
} else {
       /// IT IS NOT AN ARRAY
}
1赞 PHP Guru 3/10/2023 #25

这是一个在旧浏览器和跨框架中都有效的答案。它采用了 EcmaScript 5+ 推荐的 Array.isArray() 静态方法和 ES5 之前推荐的旧方法,并将它们组合在一起,以便您在新旧 JS 版本中都能正常工作:

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

isArray([]);//true

当然,Array.isArray() 已经有 10 多年的历史了。因此,您可能不需要支持比这更旧的浏览器。但是,您不应低估仍然存在的旧浏览器的数量。

-1赞 user7212232 8/12/2023 #26
 if(elem.length == undefined){
    // is not an array
 }else{
    // is an array
 }