Let us start with a short quiz:
What does ({}).valueOf.call(myvar) do?Short answer: it converts any value to an object (an object remains unchanged, a primitive is converted to an instance of a wrapper type). The longer answer is as follows. The section numbers refer to the ECMAScript 5 specification (ECMA-262, 5th edition).
- ({}).valueOf uses an instance of Object to access Object.prototype.valueOf.
- The call() method sets this to myvar and invokes Object.prototype.valueOf, without any (explicit) parameters.
- Object.prototype.valueOf (ECMA-262, 15.2.4.4) invokes the internal abstract operation ToObject (ECMA-262, 9.9). This operation converts a primitive to a (wrapper) object and leaves an object untouched. Thus, given a value, you always end up with an object.
> String.prototype.valueOf.call(new String("abc"))
'abc'
> String.prototype.valueOf.call("abc")
'abc'
> "abc".valueOf()
'abc' // via String.prototype.valueOf()
> Object.prototype.valueOf.call("abc")
{ '0': 'a'
, '1': 'b'
, '2': 'c'
}
> Object.prototype.valueOf.call(new String("abc"))
{ '0': 'a'
, '1': 'b'
, '2': 'c'
}
So, Object.prototype.valueOf.call() is verbose and not very intuitive for converting values to objects. A more descriptive alternative is the function Object() (emphasis below is mine).
When Object is called as a function rather than as a constructor, it performs a type conversion [to an object]. [ECMA-262, 15.2.1]Examples:
> Object("abc") instanceof String
true
> Object(new String("abc")) instanceof String
true
> Object(null)
{}
Using Object as a constructor (with new) basically has the same effect, but as a function, it better expresses the fact that there isn’t always a new object being created.
Related reading: Flattr
No comments:
Post a Comment