如何检查对象是否是 JavaScript 中的参数对象

How do I check whether an object is an arguments object in JavaScript?

本文关键字:对象 是否是 JavaScript 参数 何检查 检查      更新时间:2023-09-26

我处于 ES5 严格模式,所以解决方案

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

不幸的是不起作用。

function isArguments( item ) {
    return Object.prototype.toString.call( item ) === '[object Arguments]';
}

威廉的回答是正确的,但一些解释可能是有用的。

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

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

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

[Class]] 是所有对象通用的内部属性,其值是用于对对象进行分类的字符串。这在 §8.6.2 对象内部属性和方法中有解释:

[

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

[

[类]] 内部属性的值在内部用于 区分不同种类的对象。

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

主机对象的 [[Class]] 内部属性的值可以是 除"Arguments"之一之外的任何字符串值 , [...]

因此,要标识 Arguments 对象,只需检查其类。

您可以使用 §15.2.4.2  Object.prototype.toString 来执行此操作:

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

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

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

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

但是,没有更好的方法:

请注意,此规范不为程序提供任何方法 以访问该值,但通过 Object.prototype.toString 除外(请参阅 15.2.4.2(。

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

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