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

时间:2022-08-01 07:01:23

So i have a function that needs to check if an argument is an object, but this fails because:

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

typeof [] // returns 'object'

This is a classic javascript gotcha, but i cant remember what to do to actually accept objects, but not arrays.

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

10 个解决方案

#1


36  

Try something like this :

尝试这样的事情:

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

or (even better)

或(甚至更好)

obj instanceof Array

#2


19  

All these answers suggesting that you check to see (one way or another) if an object is an instance of the "Array" class (that is, constructed by "Array") are really not safe solutions. They'll work sometimes, maybe most of the time, but all the major frameworks have moved away from that approach. One of the main problems with it comes about when there's interaction between multiple windows (generally, a parent window and one or more frame or iframe windows). If you pass an array object created in one window into an API resident in another window, all these tests will fail. Why? Because what you're testing is whether an object is an instance of the "Array" class in your local window context. In other words, when you reference "Array" in

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

if (myobject instanceof Array) { ... }

what you're referencing is window.Array, of course. Well, an array constructed in another window is not going to be an instance of the Array class in your window!

你引用的是window.Array,当然。好吧,在另一个窗口中构建的数组不会成为窗口中Array类的实例!

Checking the constructor name is probably a little safer, though it's still risky. In my opinion, you're better off taking a duck-typing approach. That is, instead of asking, "Is this an Array?" ask instead, "does this object seem to support some particular set of Array APIs I need in this circumstance?" For example, "does this object have a length property?" Javascript is a pretty "soft" language, and just about everything's mutable. Thus even if you do find out something was constructed by "Array", you still really don't know for sure what you can do with it or to it.

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

[edit] Thanks for that link, @Lachlan - here's a very clear description of the issues: http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/

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

#3


9  

To determine whether a given object is an array, ECMAScript 5 introduces the Array.isArray() method, which is currently supported across all modern browsers. Refer to this ECMAScript compatibility table.

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

To determine the class of a particular object, you can use the Object.prototype.toString() method.

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

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

#4


4  

For what it's worth, here is how jQuery checks whether something is an array:

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

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

But, this article recommends doing it like this:

但是,本文建议这样做:

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

#5


4  

Arrays are objects in javascript after all ,so all you need to do is to check if the type of variable is an object and in the same time this object is not instance of Array class.

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

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

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

#6


3  

To test if something is an instance of an Array:

要测试某些东西是否是数组的实例:

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

To test is something is an instance of an Object:

要测试是某个对象的实例:

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

Note the latter would throw an error if obj is null or undefined, in that case you could use: typeof obj === 'object' or just do a null check: obj && obj.constructor === Object.

注意,如果obj为null或未定义,后者将抛出错误,在这种情况下,您可以使用:typeof obj ==='object'或只执行null检查:obj && obj.constructor === Object。

#7


2  

Have you tried this:

你试过这个:

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

EDIT: This method doesn't work in multi-frame DOM environments (‘typeof’ considered useless - or how to write robust type checks). (via Pointy)

编辑:此方法不适用于多帧DOM环境('typeof'被认为无用 - 或如何编写健壮的类型检查)。 (通过Pointy)

#8


0  

Look this package

看看这个包

Verify if a given object is not an array for old browsers

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

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

#9


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);

Let input be an Array or an Object

设输入为数组或对象

To check if an object is an Array
if(Object.prototype.toString.call(input) === '[object Array]') {}

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

To check if an object is an Object
if(Object.prototype.toString.call(input) === '[object Object]') {}

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


Please note Object.keys(input).length will return you the length for both Array and Object.

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

JS Fiddle example for the same

JS小提琴的例子也一样

#10


0  

please use Object.prototype.toString.call({}).slice(8,-1)==="Object" this works for all datatype you can replace the parameter inside call function and the comparison also to check for different datatypes. it works for null check as well

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

#1


36  

Try something like this :

尝试这样的事情:

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

or (even better)

或(甚至更好)

obj instanceof Array

#2


19  

All these answers suggesting that you check to see (one way or another) if an object is an instance of the "Array" class (that is, constructed by "Array") are really not safe solutions. They'll work sometimes, maybe most of the time, but all the major frameworks have moved away from that approach. One of the main problems with it comes about when there's interaction between multiple windows (generally, a parent window and one or more frame or iframe windows). If you pass an array object created in one window into an API resident in another window, all these tests will fail. Why? Because what you're testing is whether an object is an instance of the "Array" class in your local window context. In other words, when you reference "Array" in

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

if (myobject instanceof Array) { ... }

what you're referencing is window.Array, of course. Well, an array constructed in another window is not going to be an instance of the Array class in your window!

你引用的是window.Array,当然。好吧,在另一个窗口中构建的数组不会成为窗口中Array类的实例!

Checking the constructor name is probably a little safer, though it's still risky. In my opinion, you're better off taking a duck-typing approach. That is, instead of asking, "Is this an Array?" ask instead, "does this object seem to support some particular set of Array APIs I need in this circumstance?" For example, "does this object have a length property?" Javascript is a pretty "soft" language, and just about everything's mutable. Thus even if you do find out something was constructed by "Array", you still really don't know for sure what you can do with it or to it.

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

[edit] Thanks for that link, @Lachlan - here's a very clear description of the issues: http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/

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

#3


9  

To determine whether a given object is an array, ECMAScript 5 introduces the Array.isArray() method, which is currently supported across all modern browsers. Refer to this ECMAScript compatibility table.

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

To determine the class of a particular object, you can use the Object.prototype.toString() method.

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

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

#4


4  

For what it's worth, here is how jQuery checks whether something is an array:

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

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

But, this article recommends doing it like this:

但是,本文建议这样做:

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

#5


4  

Arrays are objects in javascript after all ,so all you need to do is to check if the type of variable is an object and in the same time this object is not instance of Array class.

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

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

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

#6


3  

To test if something is an instance of an Array:

要测试某些东西是否是数组的实例:

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

To test is something is an instance of an Object:

要测试是某个对象的实例:

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

Note the latter would throw an error if obj is null or undefined, in that case you could use: typeof obj === 'object' or just do a null check: obj && obj.constructor === Object.

注意,如果obj为null或未定义,后者将抛出错误,在这种情况下,您可以使用:typeof obj ==='object'或只执行null检查:obj && obj.constructor === Object。

#7


2  

Have you tried this:

你试过这个:

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

EDIT: This method doesn't work in multi-frame DOM environments (‘typeof’ considered useless - or how to write robust type checks). (via Pointy)

编辑:此方法不适用于多帧DOM环境('typeof'被认为无用 - 或如何编写健壮的类型检查)。 (通过Pointy)

#8


0  

Look this package

看看这个包

Verify if a given object is not an array for old browsers

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

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

#9


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);

Let input be an Array or an Object

设输入为数组或对象

To check if an object is an Array
if(Object.prototype.toString.call(input) === '[object Array]') {}

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

To check if an object is an Object
if(Object.prototype.toString.call(input) === '[object Object]') {}

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


Please note Object.keys(input).length will return you the length for both Array and Object.

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

JS Fiddle example for the same

JS小提琴的例子也一样

#10


0  

please use Object.prototype.toString.call({}).slice(8,-1)==="Object" this works for all datatype you can replace the parameter inside call function and the comparison also to check for different datatypes. it works for null check as well

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