所以我有一个函数需要检查一个参数是否是一个对象,但是这个失败是因为:
typeof [] // returns 'object'
这是一个经典的javascript问题,但我不记得该怎么做才能真正接受对象,而不是数组。
答案 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
注意如果obj
为null
或undefined
,后者会抛出错误,在这种情况下,您可以使用: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)
答案 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
成为Array
或Object
检查对象是否为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[])
{
...
}