6

Why does JavaScript have boxed versions of primitives?

Like, I'm good with true and false, why do I need

new Boolean(true) === new Boolean(true) // false

I get that languages like Java and Objective-C had the boxed things because you couldn't put primitives into the same data structures as non-primitives. But JS always allowed arrays of mixed things [1, 2, {}, ""] and anything could be the value for a key in an object.

I'm not asking for a justification: of course capital "B" Boolean is nonsense. But I'm genuinely curious about how this happened. There must have been a reason at the time.

Max Heiber
  • 14,346
  • 12
  • 59
  • 97
  • 1
    Does this answer your question? [What is the purpose of new Boolean() in Javascript?](https://stackoverflow.com/questions/856324/what-is-the-purpose-of-new-boolean-in-javascript) – Hamms Mar 31 '20 at 21:32
  • @Hamms I don't think it does – Bergi Mar 31 '20 at 21:57

1 Answers1

9

JavaScript has boxed primitive types so that their instances can inherit properties (especially methods) from their prototypes, which fits in well with the auto-boxing of the receiver value on property access (and method calls).

For example

Boolean.prototype.demo = "!";
console.log(true.demo);
console.log(true.toString());

Contrast this to undefined.toString(), which is not auto-boxed.

This reason is confirmed by the creator of the language:

the so-called primitive types Boolean, Number, and String each have a corresponding Object subtype: Boolean, Number, and String respectively. When a primitive value is used as an object, it is automatically “boxed” or wrapped by a new instance of the corresponding object subtype. When used in an appropriate primitive type context, the box/wrapper converts back to the primitive value.

However, he actually was rather unhappy with that, and wanted to change the type system for ES4 (which, we all known, never happened).

The question could actually even have been framed the other way round: "Why does JavaScript have primitive types when it already has Boolean, Number and String objects?". They really aren't necessary at all, many languages do fine without them and just live the object-oriented everything is an object maxim - including languages that were the inspirations for JS.

Again, we learn from Brendan Eich:

The diktat from upper engineering management was that the language must “look like Java”. […]

I’m not proud, but I’m happy that I chose Scheme-ish first-class functions and Self-ish (albeit singular) prototypes as the main ingredients. The Java influences, especially y2k Date bugs but also the primitive vs. object distinction (e.g., string vs. String), were unfortunate.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • To Eich's quote: it seems that auto-boxing / unboxing doesn't happen allways: it happens here `myfunc.call(5) // Number {5}`, but not here `new Proxy(5,{}) // TypeError` – Jan Turoň Jun 19 '23 at 11:05
  • @JanTuroň It generally only happens when you access a property. For the `this` value in `myfunc`, it only happens if you are not using strict mode (which you really should). – Bergi Jun 19 '23 at 12:32