在javascript中,我们如何确定对象是哈希还是数组?


76

我的JSON调用的输出可以是Array或Hash。如何区分这两个?

Answers:


124

现代浏览器支持该Array.isArray(obj)方法。

有关文档和polyfill,请参阅MDN

= 2008年的原始答案=

您可以使用输出的constuctor属性:

if(output.constructor == Array){
}
else if(output.constructor == Object){
}

2
这有可能在不同页面之间发生冲突,因为它们都具有ArrayObject构造函数的不同实例,因此无法进行比较。我不太确定如何制作一个示例来说明这一点,但是我在某处阅读了该示例。
ripper234

1
@ ripper234问题将在多种window环境中显现。
alex 2012年

3
+1表示Array.isArray。检查此链接以获得借款人支持:kangax.github.io/compat-table/es5/#Array.isArray
SKuijers

1
任何使用underscore.js的人都可能会发现isArrayisObject有用。
akotian

1
不幸的是,@akotian _.isObject对于数组和哈希均返回true。您将需要其他条件逻辑来解决带有下划线的解决方案。
Con Antonakos

31

是对象:

function isObject ( obj ) {
   return obj && (typeof obj  === "object");
}

是数组:

function isArray ( obj ) { 
  return isObject(obj) && (obj instanceof Array);
}

因为数组是对象,所以您要先测试变量是否是数组,然后再测试它是否是对象:

if (isArray(myObject)) {
   // do stuff for arrays
}
else if (isObject(myObject)) {
   // do stuff for objects
}

1
好答案。您可能要添加每个js对象,可以将其视为哈希。
皮肤科医生

isObject(new Date()))为true,但就此问题而言,日期不是对象/哈希。当然,我们只是将其应用于JSON,但是方法名称确实令人困惑。
schirrmacher

isObject对于对象和数组都返回true,因此是多余的
hacklikecrack

9

您是说“对象”而不是“哈希”吗?

>>> var a = [];
>>> var o = {};
>>> a instanceof Array
true
>>> o instanceof Array
false

5

我做了一个确定它是否是字典的函数。

exports.is_dictionary = function (obj) {
    if(!obj) return false;
    if(Array.isArray(obj)) return false;
    if(obj.constructor != Object) return false;
    return true;
};

// return true
test.equal(nsa_utils.is_dictionary({}), true);
test.equal(nsa_utils.is_dictionary({abc:123, def:456}), true);

// returns false
test.equal(nsa_utils.is_dictionary([]), false);
test.equal(nsa_utils.is_dictionary([123, 456]), false);
test.equal(nsa_utils.is_dictionary(null), false);
test.equal(nsa_utils.is_dictionary(NaN), false);
test.equal(nsa_utils.is_dictionary('hello'), false);
test.equal(nsa_utils.is_dictionary(0), false);
test.equal(nsa_utils.is_dictionary(123), false);

谢谢你 它适用于上述情况。我还必须解决您的方法失败的情况。
导航

1
if(Array.isArray(obj)) return false;<-考虑到数组无论如何都不会通过下一个检查,这不是多余的if(obj.constructor != Object)吗?

assert.equal(is_dictionary(new (class MyClass {})), true);失败-MyClass的实例一定是哈希/字典。
Angelos Pikoulas

对其进行了一些改进:const assert = require('assert'); const is_dictionary = function (obj) { if(!obj) return false; if(Array.isArray(obj)) return false; if (({}).toString.apply(obj) !== '[object Object]') return false; return true; }; // returns true along your own with these values new (class MyClass {}) Object.create({}) Object.create(null) // returns false along with yours new String('foo') new Number(123) ()=> {} function() {} new Map
Angelos Pikoulas

1

检查对象的“构造函数”属性。它是数组-它是一个数组对象。

var a = {
 'b':{length:0},
 'c':[1,2]
}

if(构造函数==数组)
   对于(var i = 0; i <aclength; i ++)
      警报(ac [i]);
其他
   为(ab中的var s);
      警报(ab [s]);


0

对于解析json可能会派上用场:)

isArrayHashs = (attr) ->
  !!attr && attr.constructor == Array && isHash(attr[0])

isHash = (attr) ->
  !!attr && !$.isNumeric(attr) && attr.constructor == Object

attr [0] .constructor必须是:

  • 数字
  • 数组
  • 目的
  • 未定义

0

比对象或哈希或字典更实用和精确的术语可能是关联数组。对象可能适用于许多不良情况,例如typeof null === 'object'[1,2,3] instanceof Object。自ES3以来,以下两个功能正常工作,并且自然是排他的。

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

console.assert(true === is_array([]));
console.assert(true === is_array([1,2,3]));
console.assert(true === is_array(new Array));
console.assert(true === is_array(Array(1,2,3)));

console.assert(false === is_array({a:1, b:2}));
console.assert(false === is_array(42));
console.assert(false === is_array("etc"));
console.assert(false === is_array(null));
console.assert(false === is_array(undefined));
console.assert(false === is_array(true));
console.assert(false === is_array(function () {}));
function is_associative_array(z) {
    return Object.prototype.toString.call(z) === '[object Object]';
}

console.assert(true === is_associative_array({a:1, b:2}));
console.assert(true === is_associative_array(new function Legacy_Class(){}));
console.assert(true === is_associative_array(new class ES2015_Class{}));

console.assert(false === is_associative_array(window));
console.assert(false === is_associative_array(new Date()));
console.assert(false === is_associative_array([]));
console.assert(false === is_associative_array([1,2,3]));
console.assert(false === is_associative_array(Array(1,2,3)));
console.assert(false === is_associative_array(42));
console.assert(false === is_associative_array("etc"));
console.assert(false === is_associative_array(null));
console.assert(false === is_associative_array(undefined));
console.assert(false === is_associative_array(true));
console.assert(false === is_associative_array(function () {}));

请注意,这将如何将实例视为关联数组。(但不是内置类的实例,例如Date。)

多亏了RobG针对Array.isArray()polyfill的解决方案。这利用了Object类的本机toString()方法,该方法简洁高效地报告类型。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.