如何检查对象是不是不是数组?
Posted
技术标签:
【中文标题】如何检查对象是不是不是数组?【英文标题】:How to check if an object is not an array?如何检查对象是否不是数组? 【发布时间】:2011-01-16 23:30:10 【问题描述】:所以我有一个函数需要检查一个参数是否是一个对象,但这失败了,因为:
typeof [] // returns 'object'
这是一个经典的 javascript 陷阱,但我不记得要做什么才能实际接受对象,而不是数组。
【问题讨论】:
重复:***.com/questions/1202841/… 【参考方案1】:试试这样的:
obj.constructor.toString().indexOf("Array") != -1
或者(甚至更好)
obj instanceof Array
【讨论】:
看来您的第一个建议是最安全的,并且还可以解决下面@Pointy 所述的问题。谢谢你:) 或更准确地说:Object.prototype.toString.call(obj) === '[object Array]'; jQuery 有一个实用方法isArray()
。 api.jquery.com/jQuery.isArray@hojberg 我支持你的做法。 jQuery 内部也是如此。
如果obj
是在不同的框架中创建的,此方法将失败。如果您可以针对 ES5,Array.isArray
就没有这个问题。
我不相信这回答了这个问题,即检测一个参数是否是一个对象。提问者指出,数组在使用typeof
时会产生误报。我已经发布了一个更新的答案,应该可以处理这两种情况。【参考方案2】:
所有这些建议您检查(以一种或另一种方式)对象是否是“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/
【讨论】:
【参考方案3】:测试某事物是否是 Array 的实例:
const arr = [1,2,3];
Array.isArray(arr); // true
要测试的东西是 Object 的一个实例:
const obj = 1: 'a', 2: 'b', 3: 'c' ;
obj.constructor === Object; // true
注意如果obj
是null
或undefined
,后者会抛出一个错误,在这种情况下你可以使用:typeof obj === 'object'
或者只是做一个空检查:obj && obj.constructor === Object
.
【讨论】:
【参考方案4】:为了确定给定对象是否为数组,ECMAScript 5 引入了Array.isArray() 方法,目前所有现代浏览器都支持该方法。参考这个ECMAScript compatibility table。
要确定特定对象的类,可以使用Object.prototype.toString() 方法。
Object.prototype.toString.call(); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
【讨论】:
我更喜欢typeof
或typeof []
而不是使用原型的toString
方法。【参考方案5】:
对于它的价值,下面是 jQuery 如何检查某个东西是否是一个数组:
isArray: function( arr )
return !!arr && arr.constructor == Array;
但是,this article 建议这样做:
function isArray(o)
return Object.prototype.toString.call(o) === '[object Array]';
【讨论】:
【参考方案6】:你试过了吗:
var test = [];
if(test instanceof Array)
...
编辑:此方法不适用于多帧 DOM 环境 (‘typeof’ considered useless - or how to write robust type checks)。 (通过尖尖)
【讨论】:
不是一个很好的解决方案。见juhukinners.com/2009/01/11/…【参考方案7】:看看这个包
验证给定对象是否不是旧浏览器的数组
https://www.npmjs.com/package/notisarray
【讨论】:
【参考方案8】: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
将返回数组和对象的长度。
JS Fiddle example 相同
【讨论】:
【参考方案9】:请使用Object.prototype.toString.call().slice(8,-1)==="Object"
这适用于所有数据类型,您可以替换调用函数内的参数,并且比较也可以检查不同的数据类型。它也适用于空值检查
【讨论】:
这似乎比typeof === 'object'
更复杂
typeof 关键字存在错误。如果你这样做typeof null
,那也将返回“对象”。这个解决方案更通用。
好点,然后我会做类似thing && typeof thing === 'object'
以上是关于如何检查对象是不是不是数组?的主要内容,如果未能解决你的问题,请参考以下文章