如何检查对象是否不是数组?

时间:2010-02-15 12:38:54

标签: javascript types typeof

所以我有一个函数需要检查一个参数是否是一个对象,但是这个失败是因为:

typeof [] // returns 'object'

这是一个经典的javascript问题,但我不记得该怎么做才能真正接受对象,而不是数组。

11 个答案:

答案 0 :(得分:40)

尝试这样的事情:

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

或(甚至更好)

obj instanceof Array

答案 1 :(得分:20)

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

中引用“数组”时
if (myobject instanceof Array) { ... }

您所引用的内容当然是window.Array。好吧,在另一个窗口中构建的数组将成为窗口中Array类的一个实例!

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

[编辑]感谢@Lachlan的链接 - 这里有一个非常明确的问题描述:http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/

答案 2 :(得分:10)

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

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

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

答案 3 :(得分:6)

测试某些内容是否是数组的实例:

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

答案 4 :(得分:5)

数组毕竟是javascript中的对象,所以你需要做的就是检查变量的类型是否是一个对象,同时这个对象不是Array类的实例。

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

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

答案 5 :(得分:4)

对于它的价值,这里是jQuery如何检查某些东西是否为数组:

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

但是,this article建议这样做:

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

答案 6 :(得分:2)

你试过这个:

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

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

答案 7 :(得分:0)

查看此包

验证给定对象是否不是旧浏览器的数组

https://www.npmjs.com/package/notisarray

答案 8 :(得分: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) {
    	str = str + obj[k] + ' ';
    }
    console.log('I love ', str);
    alert('I love ' + str);
} else {
	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);

input成为ArrayObject

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

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


请注意Object.keys(input).length将返回Array和Object的长度。

JS Fiddle example用于相同的

答案 9 :(得分:0)

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

答案 10 :(得分:0)

您可以申请

if(refernce_name instanceOf Object[])
{ 
 ...
}