【问题标题】:How do I check whether an object is an arguments object in JavaScript?如何检查一个对象是否是 JavaScript 中的参数对象?
【发布时间】:2011-10-05 03:01:42
【问题描述】:

我是ES5严格模式,所以解决办法

function isArguments(item) {
    return item.callee !== undefined;
}

很遗憾没用。

【问题讨论】:

  • 任何特定的引擎或解决方案是否必须是通用的?
  • 您只想检查具有length 属性的Object 吗?
  • 请注意,即使您不在严格模式下,上述方法也并非完全可靠:alert(isArguments({"callee" : "test"})); - 我同意 alex 的观点,即检查 length 属性是一个合理的折衷方案。

标签: javascript


【解决方案1】:
function isArguments( item ) {
    return Object.prototype.toString.call( item ) === '[object Arguments]';
}

【讨论】:

  • +1。请注意,UnderscoreLodash 库将其作为辅助函数 _.isArguments 提供。
  • 请注意,ES6 增加了Symbol.toStringTag,它提供了一种自定义Object.prototype.toString 的结果的方法。因此,在最新版本的 JavaScript 中可以打破这种检查。
【解决方案2】:

William's answer 是对的,但一些解释可能有用。

在 ECMAScript 5 中,Arguments 对象的唯一特征是它们的内部 [[Class]],如 §10.6 Arguments Object 所示:

当 CreateArgumentsObject 被调用时,以下步骤是 执行:

  • obj 成为创建新 ECMAScript 对象的结果。
  • obj的[[Class]]内部属性设置为"Arguments"
  • 返回对象

[[Class]] 是所有对象共有的内部属性,其值是对对象进行分类的字符串。这在§8.6.2 Object Internal Properties and Methods中有解释:

[[Class]] 内部属性的值由此定义 每种内置对象的规范。

[[Class]] 内部属性的值在内部用于 区分不同种类的物体。

此外,请注意宿主对象不会有问题:

宿主对象的 [[Class]] 内部属性的值可能是 除了 "Arguments", [...]

之一之外的任何字符串值

因此,要识别 Arguments 对象,您只需检查其类即可。

您可以使用§15.2.4.2 Object.prototype.toString

  • O 成为调用 ToObject 并传递 this 值作为参数的结果。
  • classO 的 [[Class]] 内部属性的值。
  • 返回字符串值,它是三个字符串"[object "class"]" 连接的结果。

因此,您可以使用Function.prototype.call 调用该方法,并将this 值设置为您要检查的对象。当且仅当它是一个 Arguments 对象时,返回的字符串将为 '[object Arguments]'

Object.prototype.toString.call(obj) == '[object Arguments]'

请注意,这并非完全万无一失,因为全局 Object 可能已被本地覆盖,或者全局 Object 或其 toString 属性可能已被修改。

但是,没有更好的办法:

请注意,本规范没有为程序提供任何方法 访问该值,除非通过 Object.prototype.toString(请参阅 15.2.4.2)。

【讨论】:

    【解决方案3】:

    生成和比较字符串以确定对象的类型有点模糊。就像@bergi 建议的那样,我认为Lodash 这样做是一种更方便的方式。浓缩成一个函数就是:

    function isArguments(value) {
        return !!value && typeof value == 'object' && Object.prototype.hasOwnProperty.call(value, 'callee') && !Object.prototype.propertyIsEnumerable.call(value, 'callee');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      • 2010-09-27
      • 1970-01-01
      • 2012-05-31
      • 2016-06-05
      • 2020-03-23
      相关资源
      最近更新 更多