Portrait Dr. Axel Rauschmayer
Dr. Axel Rauschmayer
Homepage | Twitter
Cover of book “Exploring ES6”
Book, exercises, quizzes
(free to read online)
Logo of newsletter “ES.next news”
Newsletter (free)
Cover of book “JavaScript for impatient programmers”
Book (free online)

JavaScript: converting any value to an object

[2011-04-17] dev, javascript, jslang
(Ad, please don’t block)

This post is about converting between primitive values and wrapper objects [1]. Thankfully, one is usually not faced with this kind of task in JavaScript. The most frequent use case is to add properties to a primitive. As a primitive is immutable, you need to convert it to a wrapper object to do so. Read on if you want to see some of JavaScript’s more obscure corners.

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, 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.
This is a bit illogical, because in all subtypes of Object, valueOf() is about converting from a wrapper to a primitive (i.e., the opposite direction).
    > String.prototype.valueOf.call(new String("abc"))
    > String.prototype.valueOf.call("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]
    > Object("abc") instanceof String
    > Object(new String("abc")) instanceof String
    > 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:
  1. JavaScript values: not everything is an object