在Javascript中区分数组和“哈希”

时间:2010-07-09 17:24:34

标签: javascript

为了使我的一个函数的语法更好,我需要能够判断一个特定参数是一个数组还是“哈希”(我知道它只是对象)。

Typeof不起作用,因为它们都返回相同的东西

typeof {foo:"bar"} // Object

typeof ["foo","bar"] // Object

那么我如何区分这两者?

我知道有效,但我希望有一个更好的方式

({foo:"bar"}).constructor // Object()

(["foo","bar"]).constructor // [ undefined ]

修改 啊,在firebug中似乎[undefined]与Array相同。有点奇怪。

5 个答案:

答案 0 :(得分:11)

你可以像SLaks建议的那样检查长度属性,但是一旦你传递了一个函数对象,你就会感到惊讶,因为它实际上有一个length属性。此外,如果对象定义了一个length属性,你将再次得到错误的结果。

你最好的选择可能是:

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

jQuery使用它,以及一对“其他人......”)

它比实例方式更失败。该方法也由以下文章提出:

'instanceof' considered harmful (or how to write a robust 'isArray') (@ kagax)

另外要补充的是,此功能几乎与ES 5规范中的Array.isArray功能相同:

  

15.4.3.2 Array.isArray(arg)

     
      
  1. 如果Type( arg )不是Object,则返回   的即可。
  2.   
  3. 如果[[Class]]的值    arg 的内部属性是“数组”,   然后返回 true
  4.   
  5. 返回 false
  6.   

答案 1 :(得分:7)

something instanceof Array在单个文档中正常工作,但如果您开始在不同窗口之间传递数组,则会失败,因为一个窗口中的Array与另一个窗口中的Array不同。如果您无意进行跨窗口脚本编写(一般情况下,值得避免),我建议您坚持使用。

如果您需要跨窗口支持,事情会更复杂一些。在未来,故事很简单,因为ECMAScript第五版定义了一个功能来完成这个:

Array.isArray([1]);   // -> true

您应该使用此功能,因为它是唯一可靠且标准认可的方式。但是,今天的许多浏览器还不支持它。

如果它不可用,你必须依赖Object#toString序列化,这是丑陋的,有点狡猾。虽然它通常可以在今天的浏览器中可靠地工作,但是可以想象它可能没有(主要与宿主对象有关)。

您可以在不支持此浏览器的浏览器上将此回退方法修改为Array,然后始终使用Array.isArray

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

对于constructor,永远不要使用它。它并非在任何地方都可用,它没有按照您的想法行事。使用它几乎总是一个错误。

答案 2 :(得分:3)

我认为最优雅的方法是简单地使用instanceof运算符:

if (myVar instanceof Array)
    doSomething();

示例:

[] instanceof Array           // true
{} instanceof Array           // false
{length:100} instanceof Array // false
null instanceof Array         // false

编辑:

请注意,从另一个iFrame测试对象时会失败(请参阅@galambalazs和@bobince的答案)

答案 3 :(得分:1)

检查length属性:

"length" in {foo:"bar"}   //false
"length" in ["foo","bar"] //true

答案 4 :(得分:0)

此typeof函数用于纠正typeof运算符的数组/对象冲突, null / object碰撞。但是它不能跨框架或跨窗口工作。请参阅源代码以获取适用于这些版本的更高级版本。

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (value instanceof Array) {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

来源:Douglas Crockford's Javascript site