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

Javascript 如何检查对象是否不是数组?,javascript,types,typeof,Javascript,Types,Typeof,因此,我有一个函数需要检查一个参数是否是对象,但这失败了,因为: typeof [] // returns 'object' 这是一个经典的javascript问题,但我记不起如何实际接受对象,而不是数组。试试下面的方法: obj.constructor.toString().indexOf("Array") != -1 或者(更好) 你试过这个吗: var test = []; if(test instanceof Array) { ... } 编辑:此方法不适用于多帧DOM环境()。

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

typeof [] // returns 'object'

这是一个经典的javascript问题,但我记不起如何实际接受对象,而不是数组。

试试下面的方法:

obj.constructor.toString().indexOf("Array") != -1
或者(更好)

你试过这个吗:

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

编辑:此方法不适用于多帧DOM环境()。(通过Pointy)

所有这些答案都建议您(以某种方式)检查对象是否是“Array”类的实例(即,由“Array”构造的对象),这些答案都不是安全的解决方案。它们有时会起作用,也许大部分时间都会起作用,但所有主要的框架都不再采用这种方法。当多个窗口(通常是父窗口和一个或多个frame或iframe窗口)之间存在交互时,它的一个主要问题就会出现。如果将在一个窗口中创建的数组对象传递到另一个窗口中驻留的API中,所有这些测试都将失败。为什么?因为您要测试的是对象是否是本地窗口上下文中“Array”类的实例。换句话说,当您在中引用“数组”时

当然,您所引用的是
window.Array
。好吧,在另一个窗口中构造的数组不是你窗口中数组类的实例

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


[编辑]感谢您的链接,@Lachlan-这里有一个非常清晰的问题描述:

关于它的价值,以下是jQuery如何检查某个东西是否是数组:

isArray: function( arr ) {
    return !!arr && arr.constructor == Array;
}
但是,建议这样做:

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

为了确定给定对象是否为数组,ECMAScript 5引入了该方法,目前所有现代浏览器都支持该方法。参考这个

要确定特定对象的类,可以使用该方法

Object.prototype.toString.call({});//“[对象]”
Object.prototype.toString.call([]);//“[对象数组]”
查看此包

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

var obj={first:'Stack',last:'Overflow'};
//var obj=['Stack','overflow']//您可以取消对此行的注释,并对上面的内容进行注释以进行检查。。
if(Object.prototype.toString.call(obj)!='[Object Array]'){
//你的代码。。
var-str='';
用于(obj中的var k){
str=str+obj[k]+'';
}
console.log('I love',str);
警惕(“我爱”+str);
}否则{
log('无法处理。可能是数组');
警报('无法处理。可能是数组');
}
log('长度为:',Object.keys(obj.Length));

警报('长度为:'+Object.keys(obj.Length))以测试某物是否是数组的实例:

const arr = [1,2,3];
Array.isArray(arr);  // true
const obj = { 1: 'a', 2: 'b', 3: 'c' };
obj.constructor === Object;  // true
测试是某事物是对象的一个实例

const arr = [1,2,3];
Array.isArray(arr);  // true
const obj = { 1: 'a', 2: 'b', 3: 'c' };
obj.constructor === Object;  // true

注意,如果
obj
null
未定义
,则后者将抛出一个错误,在这种情况下,您可以使用:
typeof obj==='object'
或只需执行null检查:
obj&&obj.constructor=='object
请使用
object.protostring.call({}).slice(8,-1)=='object
这适用于所有数据类型。您可以替换调用函数中的参数,也可以通过比较来检查不同的数据类型。它也适用于空检查

重复:您的第一个建议似乎是最安全的,并且还可以解决下面@Pointy所述的问题。谢谢:)或者更确切地说:Object.prototype.toString.call(obj)='[objectarray]';jQuery有一个实用方法
isArray()
@我支持你的做法。jQuery内部也是这样做的。如果在不同的框架中创建了
obj
,这种方法将失败<如果可以将ES5作为目标,则code>Array.isArray
没有这个问题。我不相信这回答了问题,即检测参数是否为对象。询问者指出,当使用
typeof
时,数组会产生误报。我已经发布了一个更新的答案,应该可以处理这两种情况。这不是一个好的解决方案。请看,这似乎比
typeof{}===“object”
关键字typeof中有一个bug更复杂。如果执行
typeof null
,则也将返回“object”。这个解决方案更通用。好的一点,那么我会做一些类似
thing&&typeof thing==='object'
的事情,我更喜欢
typeof{}
typeof[]
而不是使用原型的
toString
方法。