【问题标题】:Is this an acceptable way to determine if an object is an array in JavaScript?这是确定对象是否是 JavaScript 中的数组的一种可接受的方法吗?
【发布时间】:2011-07-17 04:54:27
【问题描述】:

我经常用这段代码来判断一个数组是否真的是一个数组……

Object.prototype.toString.call(array) == '[object Array]'

我最近开始将我的回调测试从 typeof callback == 'function' 更改为 callback instanceof Function,因为我读到 Safari 和 Chrome 会告诉您正则表达式文字是使用前者的函数(我测试它时确实如此)。

现在,我决定检查一下这段代码,看看是否可以替换上面的冗长代码......

array instanceof Array

成功了。

Comparison of both on jsFiddle.

那么,后一种方法有什么问题吗?我认为可能是因为第一个代码示例在 Google 中出现的频率更高。

【问题讨论】:

    标签: javascript types


    【解决方案1】:

    如果有人覆盖了您的全局 Array 变量,就会出现问题。不太可能,但如果您想要一个真正的故障安全方法,请坚持 #1。

    Demonstration on jsFiddle.

    【讨论】:

    • 谢谢,但如果I overwrite Object 会不会发生同样的情况?
    • 你不能同样轻松地覆盖Object.toString吗? - Object.prototype.toString = function(){return ":-)";} - 演示:jsbin.com/awixe4。我怀疑 JavaScript 疯了。
    • 没有没有故障安全方法
    • @alex 如果你覆盖Object 每个 JS 开发者都会找到你并得到你。
    • @Raynos 我只是用它作为例子。
    【解决方案2】:

    如果有任何帮助,jQuery.isArray 中就是这样做的:

    isArray: Array.isArray || function( obj ) {
        return jQuery.type(obj) === "array";
    }
    
    type: function( obj ) {
        return obj == null ?
                 String( obj ) :
                 class2type[ toString.call(obj) ] || "object";
    }
    

    toString:

    toString = Object.prototype.toString
    

    class2type是一个关联数组,初始化为:

    jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "),
                 function(i, name) {
                     class2type[ "[object " + name + "]" ] = name.toLowerCase();
                 });
    

    如果有任何迹象,jQuery 正在使用您的第一种方法,并对其进行了广泛的测试。

    【讨论】:

      【解决方案3】:

      在 ES5 中你可以调用:

      Array.isArray(obj);
      

      https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray

      另请参阅their note,他们说纯 Javascript 实现不能保证 100% 模拟本机代码版本。

      【讨论】:

      • 通过对最新 Chrome 的快速测试,我可以写 Array.isArray = function(){return false;}。这真的能解决问题吗?或者那不应该是可能的? (我对新的 JavaScript 不是很感兴趣,所以我很可能遗漏了一些基本事实)
      • 有趣 - 我本来希望他们使该函数不可变
      【解决方案4】:

      方法没有问题

      array instanceof Array
      

      你可以使用函数

      function is_array( mixed_var ) {    // Finds whether a variable is an array
          return ( mixed_var instanceof Array );
      }
      

      【讨论】:

      • 如果您查看 Alnitak 答案中非常有趣的链接,您会发现它并非在所有情况下都有效,例如当 mixed_var 来自另一个窗口时,这种情况称为“Pfui” .
      【解决方案5】:

      instanceof 用于数组的两个问题是:

      • 当数组来自另一个窗口或框架时返回false
      • 如果 Array 构造函数被覆盖则中断

      以下是 kangax 的一篇文章,我第一次看到你的第一个技术(也用于 jQuery):http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

      【讨论】:

        【解决方案6】:

        另一种方法是 Ext 的做法:

        function isArray (obj) {
            return obj != null && typeof obj == 'object' && 'splice' in obj && 'join' in obj;
        }
        

        这依赖于检查拼接和连接的存在。应该只在数组中的两个函数。当然,如果您传递一个对象,该对象具有名为 splice 和 join 的函数(并且不是数组),那么这将失败,但您可能一开始就不应该这样做。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-14
          • 1970-01-01
          • 2018-07-17
          • 1970-01-01
          • 1970-01-01
          • 2011-09-21
          • 2017-07-04
          • 2010-10-03
          相关资源
          最近更新 更多