【问题标题】:Detect if parameter passed is an array? Javascript [duplicate]检测传递的参数是否为数组? Javascript [重复]
【发布时间】:2011-02-15 07:43:50
【问题描述】:

可能重复:
How to detect if a variable is an array

我有一个简单的问题:

如何检测传递给我的 javascript 函数的参数是否为数组?我不相信我可以测试:

if (typeof paramThatCouldBeArray == 'array') 

那么有可能吗?

我该怎么做?

提前致谢。

【问题讨论】:

  • 嗯...这让我想。如果可以传递其他任何东西,也许我的功能设计很糟糕。但我更多地问这个是因为console.log()。这让我很感兴趣,因为如果你给它传递一个数组,它会遍历整个数组并打印出来。而如果你只传递一个字符串,它只会记录下来。它是如何做到的?
  • 抱歉,为了连续性,删除的评论是“参数还可以是什么其他类型?”
  • @Alex:在哪个浏览器中?它可能依赖于Array.toString
  • 他们似乎使用了很多与浏览器相关的检查——检查getfirebug.com/releases/lite/1.2/firebug-lite.js的第1992行
  • @Alex:请注意,在 Chrome 中,console.log 是一个原生函数,因此可以访问 JS 脚本无法访问的信息。

标签: javascript arrays arguments parameter-passing


【解决方案1】:

你可以测试constructor属性:

if (param.constructor == Array) {
    ...
}

虽然这将包括具有数组原型的对象,

function Stack() {
}
Stack.prototype = [];

除非他们也定义了构造函数:

Stack.prototype.constructor = Stack;

或:

function Stack() {
    this.constructor = Stack;
}

【讨论】:

    【解决方案2】:

    我找到了这个here

    function isArray(obj) {
        return obj.constructor == Array; 
    }
    

    还有这个

    function isArray(obj) {
        return (obj.constructor.toString().indexOf(”Array”) != -1);
    }
    

    【讨论】:

    • 使用 JScript 测试 obj.constructor.toString() 返回 function Array() { [native code] },使该解决方案适用于该环境。
    【解决方案3】:
    if (param instanceof Array)
        ...
    

    编辑。截至2016年,有一个现成的方法可以捕获更多的极端情况,Array.isArray,使用如下:

    if (Array.isArray(param))
        ...
    

    【讨论】:

    • 适用于大多数情况,但它不适用于跨框架环境,请查看article
    • !!param.shift 在执行速度方面会更快。 jsperf.com/instanceof-vs-method-detect
    • 可以安全地假设这将在 nodejs 下正常工作(因为我猜只有一帧)?
    • 如果你确定你不会跨帧操作(通常是这样),那么使用构造函数方法。性能对比:jsperf.com/detecting-arrays-new
    • 截至 2016 年,这仍然是一种普遍高效且可靠的解决方案。
    【解决方案4】:

    这是 jQuery 1.4.2 使用的方法:

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

    【讨论】:

    • 这个toString 比较可能看起来很奇怪,但它是处理跨框架环境的公认方式。
    • 不太明白:我根据param定义toString,然后调用isArray()?我传递的obj 是什么?这个答案的底线在哪里?
    • Tom,基本上每个对象都有一个 toString 函数,该函数被数组“覆盖”,并且根据规范返回 [object Array]。这在所有 js 实现中都是统一的。原型只是为了引用一个函数。
    • 如果 param 是字符串 "[object Array]" 怎么办?我认为在字符串上调用 toString 会返回字符串本身
    【解决方案5】:

    一些days ago我正在构建一个简单的类型检测功能,也许它对你有用:

    用法:

    //...
    if (typeString(obj) == 'array') {
      //..
    }
    

    实施:

    function typeString(o) {
      if (typeof o != 'object')
        return typeof o;
    
      if (o === null)
          return "null";
      //object, array, function, date, regexp, string, number, boolean, error
      var internalClass = Object.prototype.toString.call(o)
                                                   .match(/\[object\s(\w+)\]/)[1];
      return internalClass.toLowerCase();
    }
    

    这个函数的second variant更加严格,因为它只返回ECMAScript规范中描述的对象类型(可能的输出值:"object""undefined""null""function""array""date""regexp""string""number""boolean""error",使用[[Class]]内部属性)。

    【讨论】:

    • CMS,您与 Gist 的两个链接都已失效。你还有那个代码吗?
    【解决方案6】:

    鸭子打字

    实际上,您不一定要检查对象是否为数组。您应该 duck type 它,并且您希望该对象实现的唯一事情是 length 属性。在此之后,您可以将其转换为数组:

    var arrayLike = {
        length : 3,
    
        0: "foo"
    };
    
    // transform object to array
    var array = Array.prototype.slice.call(arrayLike);
    
    JSON.stringify(array); // ["foo", null, null]
    

    Array.prototype.slice.call(object) 将把每个暴露了length 属性的对象转换成一个数组。以字符串为例:

    var array = Array.prototype.slice.call("123");
    JSON.stringify(array); // ["1", "2", "3"]
    

    嗯,这种技术在 IE6 上不太适用(我不知道以后的版本),但很容易创建一个小的实用程序函数来转换数组中的对象。

    【讨论】:

      猜你喜欢
      • 2019-07-21
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 2019-11-12
      相关资源
      最近更新 更多