2010-02-15 91 views
24

所以我有一个需要检查一个参数是一个对象的功能,但这种失败,因为:如何检查一个对象是不是一个数组?

typeof [] // returns 'object' 

这是一个经典的javascript疑难杂症,但我不记得做实际接受的对象是什么,但不是数组。

+2

重复:http://stackoverflow.com/questions/1202841/what-is-the-best-way-to-check-if-an-object-is-an-array-或者,未在JavaScript的 – 2010-02-15 12:46:35

回答

30

尝试这样:

obj.constructor.toString().indexOf("Array") != -1 

或(甚至更好)

obj instanceof Array 
+0

看来你的第一个建议是最安全的一个,也将解决由下面@Pointy陈述的问题。 谢谢:) – hojberg 2010-02-15 13:04:23

+0

或更精确地说:Object.prototype.toString.call(OBJ)=== '[对象阵列]'; – hojberg 2010-02-15 13:05:39

+1

jQuery有一个实用方法'IsArray的()'。 http://api.jquery.com/jQuery.isArray/ @hojberg我支持你做这件事的方式。jQuery内部也是这样。 – 2010-02-15 14:12:54

2

您是否尝试过这样的:

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

编辑:此方法不起作用在多帧DOM环境中(‘typeof’ considered useless - or how to write robust type checks)。 (via Pointy

+0

不是一个很好的解决方案。见http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/ – Pointy 2010-02-15 13:07:37

+0

好点。我不知道。 – 2010-02-15 14:07:06

17

所有这些答案都表明,如果对象是“Array”类的实例(即由“Array”构造),则检查是否看到(以某种方式)安全的方案。他们有时可能会工作,也许大部分时间都在工作,但所有主要框架已经从这种方法中移开。它的主要问题之一是当多个窗口(通常是父窗口和一个或多个框架或iframe窗口)之间存在交互时。如果将在一个窗口中创建的数组对象传递到驻留在另一个窗口中的API,则所有这些测试都将失败。为什么?因为您正在测试的是对象是否是本地窗口上下文中的“Array”类的实例。换句话说,当你在

if (myobject instanceof Array) { ... } 

参考“阵列”什么你引用是window.Array,当然。那么,在构造的另一个窗口中的数组是而不是将成为窗口中的Array类的实例!

检查构造函数的名称可能会更安全一些,但它仍然有风险。在我看来,你最好采用鸭子打字的方式。也就是说,不是问,“这是一个数组吗?”反而问,“这个对象似乎是否支持我在这种情况下需要的一些特定的数组API?”例如,“该对象是否具有length属性?” Javascript是一个非常“软”的语言,几乎所有的东西都是可变的。因此,即使你确实发现了某些东西是由“阵列”构成的,你仍然不知道你可以用它做什么或对它做什么。

[编辑]谢谢你提供的链接,@Lachlan - 这里的问题非常明确的说明:http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/

+0

+1以获得很好的解释。感谢您的支持 – 2010-02-24 16:06:05

3

对于它的价值,这里是jQuery的检查东西是否是一个数组:

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

但是,this article建议做这样的:

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

为了确定一个给定的对象是否是一个数组,ECMAScript的5引入了Array.isArray()方法,目前支持所有现代浏览器。请参阅此ECMAScript compatibility table

要确定特定对象的类别,可以使用Object.prototype.toString()方法。

Object.prototype.toString.call({}); // "[object Object]" 
 
Object.prototype.toString.call([]); // "[object Array]"

2

数组是JavaScript对象毕竟,因此,所有你需要做的是检查变量的类型是一个对象,并在同一时间这个对象不是阵列的实例类。

var obj = {fname:'John',lname:'Doe'}; 

if(typeof obj === 'object' && !(obj instanceof Array)){ 
    return true ; 
} else { 
    return false; 
} 
+0

虽然这可能是一个有效的答案,但您更可能通过解释代码的作用和工作方式来帮助他人。仅有代码的答案往往会得到较少的积极关注,并没有其他答案那么有用。 – Aurora0001 2016-11-30 15:02:33

+1

@ Aurora0001可能你是对的,这里是一个简单的说明:) – 2016-12-01 08:40:34

0

var obj = {first: 'Stack', last: 'Overflow'}; 
 
// var obj = ['Stack', 'overflow']; //You can uncomment this line and comment the above to check.. 
 

 
if(Object.prototype.toString.call(obj) !== '[object Array]') { 
 
    //your code.. 
 
    var str = ''; 
 
    for(var k in obj) { 
 
    \t str = str + obj[k] + ' '; 
 
    } 
 
    console.log('I love ', str); 
 
    alert('I love ' + str); 
 
} else { 
 
\t console.log('Could not process. Probably an array'); 
 
    alert('Could not process. Probably an array'); 
 
} 
 

 
console.log('Length is: ', Object.keys(obj).length); 
 
alert('Length is: ' + Object.keys(obj).length);
数组

inputArrayObject

要检查的对象是Array
if(Object.prototype.toString.call(input) === '[object Array]') {}

要检查的对象是一个Object
if(Object.prototype.toString.call(input) === '[object Object]') {}


请注意Object.keys(input).length将返回长度为两数组和对象。

JS Fiddle example为同一

2

为了测试某个东西是阵列的一个实例:

const arr = [1,2,3]; 
Array.isArray(arr); // true 

要测试的东西是一种对象的一个实例:

const obj = { 1: 'a', 2: 'b', 3: 'c' }; 
obj.constructor === Object; // true 

如果objnullundefined,则后者会抛出错误,在这种情况下,您可以使用:typeof obj === 'object'或仅执行空值检查:obj && obj.constructor === Object

1

请使用Object.prototype.toString.call({}).slice(8,-1)==="Object"这适用于所有数据类型,您可以替换调用函数内部的参数,也可以比较以检查不同的数据类型。它适用于空检查以及

相关问题