Reputation: 395
I'm in ES5 strict mode, so the solution
function isArguments(item) {
return item.callee !== undefined;
}
unfortunately doesn't work.
Upvotes: 13
Views: 4080
Reputation: 834
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:
function isArguments(value) {
return !!value && typeof value == 'object' && Object.prototype.hasOwnProperty.call(value, 'callee') && !Object.prototype.propertyIsEnumerable.call(value, 'callee');
}
Upvotes: 1
Reputation: 288280
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:
When CreateArgumentsObject is called the following steps are performed:
- Let obj be the result of creating a new ECMAScript object.
- Set the [[Class]] internal property of obj to
"Arguments"
.- Return 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:
The value of the [[Class]] internal property is defined by this specification for every kind of built-in object.
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"
, [...]
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
:
- Let O be the result of calling ToObject passing the this value as the argument.
- Let class be the value of the [[Class]] internal property of O.
- Return the String value that is the result of concatenating the three Strings
"[object "
, class, and"]"
.
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.
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.
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).
Upvotes: 9
Reputation: 20235
function isArguments( item ) {
return Object.prototype.toString.call( item ) === '[object Arguments]';
}
Upvotes: 29