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

时间:2011-10-05 03:01:42

标签: javascript

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

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

遗憾的是不起作用。

3 个答案:

答案 0 :(得分:26)

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

答案 1 :(得分:6)

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

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

  

调用CreateArgumentsObject时,以下步骤为   进行:

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

[[Class]]是所有对象共有的内部属性,其值为String,用于对对象进行分类。这在§8.6.2 Object Internal Properties and Methods

中有解释
  

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

     

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

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

  

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

之一除外

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

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

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

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

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

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

然而,没有更好的方法:

  

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

答案 2 :(得分:0)

生成和比较字符串以确定对象的类型有点模糊。就像@bergi建议的那样,我认为Lodash正在以更方便的方式进行。凝聚成一个功能是:

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