I know sometimes JS might make you want to punch someone. At least figuratively.
However, that is not the type of boxing this article's title is referring to. The type of boxing in question here is the concept of wrapping a primitive non-object with a corresponding wrapper object.
undefined) that provide them.
But if primitives have no methods and are not objects then how does this work:
Lets do some introspection of
"foo" and see what clues we might find.
"foo".constructor === String; // true "foo".__proto__ === String.prototype; // true "foo" instanceof String; // false typeof "foo"; // "string" new String("foo") instanceof String; // true typeof new String("foo"); // "object"
We clearly have two different types of data here:
"foo"which is a
new String("foo")which is an
The latter is the only one that is an instance of
String. It is also the only one with a constructor of
String. So then what is happening?
When you try to access a property on a primitive value, behind the scenes that primitive value gets automatically boxed into (or wrapped by) it's corresponding object.
It's important to understand that the wrapper object is ephemeral. Consider:
var objectStr = new String("foo"); objectStr.bar = 2; console.log(objectStr.bar); // 2 var primitiveStr = "foo"; primitiveStr.bar = 2; console.log(primitiveStr.bar); // undefined
At this point you might be thinking that this explains why you cannot call methods directly on number literals:
5.toString(); // SyntaxError: Unexpected token ILLEGAL
One might assume that this means primitive numbers simply do not get autoboxed. This has nothing to do with boxing though. As you can see, if you reference the number using an identifier it boxes just fine:
var five = 5; typeof five; // "number" five.toString(); // "5"
Lastly, you can manually box and unbox values by casting primitives to an
Object and invoking
valueOf on wrapper objects, respectively:
var primitiveStr = "foo"; var objectStr = Object(primitiveStr); var objectNum = new Number(5); var primitiveNum = objectNum.valueOf();