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

时间:2022-01-20 20:57:02

I'm in ES5 strict mode, so the solution

我在ES5的严格模式,所以解决方案。

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

unfortunately doesn't work.

不幸的是行不通的。

3 个解决方案

#1


24  

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

#2


5  

William's answer is right, but some explanations may be useful.

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

In ECMAScript 5, the only thing that characterizes Arguments objects is their internal [[Class]], as seen in §10.6 Arguments Object:

在ECMAScript 5中,唯一特征参数的对象是他们内部[[类]],见§10.6参数对象:

When CreateArgumentsObject is called the following steps are performed:

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

  • Let obj be the result of creating a new ECMAScript object.
  • 让obj创建一个新的ECMAScript对象。
  • Set the [[Class]] internal property of obj to "Arguments".
  • 将obj的[[[Class]]]内部属性设置为“Arguments”。
  • Return obj
  • 返回obj

[[Class]] is an internal property common to all objects, whose value is a String which classifies the object. This is explained in §8.6.2 Object Internal Properties and Methods:

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

The value of the [[Class]] internal property is defined by this specification for every kind of built-in object.

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

The value of a [[Class]] internal property is used internally to distinguish different kinds of objects.

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

Moreover, note that host objects won't be problematic:

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

The value of the [[Class]] internal property of a host object may be any String value except one of "Arguments", [...]

主机对象的[[[Class]]]内部属性的值可以是任何字符串值,但“参数”除外,[…]

Therefore, to identify an Arguments object you only need to check its class.

因此,要识别参数对象,只需检查它的类。

You can do that using §15.2.4.2 Object.prototype.toString:

你可以使用§15.2.4.2 Object.prototype.toString:

  • Let O be the result of calling ToObject passing the this value as the argument.
  • 让O是调用ToObject的结果,并将此值作为参数传递。
  • Let class be the value of the [[Class]] internal property of O.
  • 让类是O的[[class]]内部属性的值。
  • Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
  • 返回字符串值,该值是连接三个字符串“[object]”、“class”和“]”的结果。

Therefore, you can use Function.prototype.call to call that method with the this value set to the object you want to check. The returned string will be '[object Arguments]' if, and only if, it's an Arguments object.

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

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

Note that isn't completely foolproof, because the global Object could have been shadowed by a local one, or the global Object or its toString property could have been modified.

注意,这并不是绝对的,因为全局对象可能被局部对象阴影,或者全局对象或其toString属性可能被修改。

However, there is no better way:

然而,没有更好的办法:

Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString (see 15.2.4.2).

注意,此规范不提供程序访问该值的任何方法,除非通过Object.prototype。toString(见15.2.4.2)。

#3


0  

Generating and comparing strings to determine the type of an object is a little fuzzy. Like @bergi suggested, I think Lodash is doing it a more convenient way. Condensed into one function it is:

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

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

#1


24  

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

#2


5  

William's answer is right, but some explanations may be useful.

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

In ECMAScript 5, the only thing that characterizes Arguments objects is their internal [[Class]], as seen in §10.6 Arguments Object:

在ECMAScript 5中,唯一特征参数的对象是他们内部[[类]],见§10.6参数对象:

When CreateArgumentsObject is called the following steps are performed:

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

  • Let obj be the result of creating a new ECMAScript object.
  • 让obj创建一个新的ECMAScript对象。
  • Set the [[Class]] internal property of obj to "Arguments".
  • 将obj的[[[Class]]]内部属性设置为“Arguments”。
  • Return obj
  • 返回obj

[[Class]] is an internal property common to all objects, whose value is a String which classifies the object. This is explained in §8.6.2 Object Internal Properties and Methods:

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

The value of the [[Class]] internal property is defined by this specification for every kind of built-in object.

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

The value of a [[Class]] internal property is used internally to distinguish different kinds of objects.

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

Moreover, note that host objects won't be problematic:

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

The value of the [[Class]] internal property of a host object may be any String value except one of "Arguments", [...]

主机对象的[[[Class]]]内部属性的值可以是任何字符串值,但“参数”除外,[…]

Therefore, to identify an Arguments object you only need to check its class.

因此,要识别参数对象,只需检查它的类。

You can do that using §15.2.4.2 Object.prototype.toString:

你可以使用§15.2.4.2 Object.prototype.toString:

  • Let O be the result of calling ToObject passing the this value as the argument.
  • 让O是调用ToObject的结果,并将此值作为参数传递。
  • Let class be the value of the [[Class]] internal property of O.
  • 让类是O的[[class]]内部属性的值。
  • Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
  • 返回字符串值,该值是连接三个字符串“[object]”、“class”和“]”的结果。

Therefore, you can use Function.prototype.call to call that method with the this value set to the object you want to check. The returned string will be '[object Arguments]' if, and only if, it's an Arguments object.

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

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

Note that isn't completely foolproof, because the global Object could have been shadowed by a local one, or the global Object or its toString property could have been modified.

注意,这并不是绝对的,因为全局对象可能被局部对象阴影,或者全局对象或其toString属性可能被修改。

However, there is no better way:

然而,没有更好的办法:

Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString (see 15.2.4.2).

注意,此规范不提供程序访问该值的任何方法,除非通过Object.prototype。toString(见15.2.4.2)。

#3


0  

Generating and comparing strings to determine the type of an object is a little fuzzy. Like @bergi suggested, I think Lodash is doing it a more convenient way. Condensed into one function it is:

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

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