Everything in JavaScript Is (Not) an Object
…Or is it?
If you had to answer whether the statement “Everything in JavaScript is an object” is true or false on Who Wants to Be a Millionaire, what would your answer be? Would you ask the audience? Phone a friend? Well, let’s just say you phoned me (risky move, honestly; but I’m honored). Now that we’re a team, let's figure this out together and win that cash money.
What Is a JavaScript Object?
From MDN:
“In JavaScript, an object is a standalone entity, with properties and type. Compare it with a cup, for example. A cup is an object, with properties. A cup has a color, a design, weight, a material it is made of, etc. The same way, JavaScript objects can have properties, which define their characteristics.”
What JavaScript structures do we already know to be objects?
Arrays, functions, and objects (obviously) are all objects in JavaScript.
What Does That Leave?
What remains are JavaScript primitives. What is a primitive? The definition is literally data that is not an object and has no methods. JS primitives are:
string
number
boolean
null
undefined
symbol
Problem Solved, Right?
So objects are objects, and primitives are not objects, and the answer to our million-dollar question is false, right? Not exactly. One main difference between objects and primitives is that objects are mutable (meaning they can be changed) but primitives are immutable (meaning they can’t be changed). The reason primitive types are immutable is that primitives have no methods attached, which means there is no possible way to mutate the string in the first place. A primitive has a value and no properties.
In JavaScript, this is all true. You cannot alter a string, which is a primitive. You can reassign a variable, but this does not affect the original value. While this fact could lead us to believe our case is closed, a problem arises when we run code like string.length
or string.split(',')
, etc. As we discovered above, if a string is truly a primitive, it should not have access to properties and methods like .length
or .slice
. That’s an ability that is limited to objects. So does that mean primitives are objects?
What’s Going On Here? Enter Autoboxing
The answer is a little bit of JavaScript magic involving wrapper-objects and autoboxing. It sounds complicated, but take a deep breath and I promise it will make sense shortly. When a method like string.length
is called on a primitive type like a string, JavaScript initiates an action called autoboxing.
Autoboxing is the process by which JavaScript wraps a primitive in an object, but only temporarily. As detailed by Daniel Li,
String
is a global function that creates a primitive string when passed in an argument, but you can also use theString
function as a constructor function. And this will create a new object (often referred to as wrapper object) representing the string"dog"
, with the following properties:
const pet = new String("dog"){
0: "d",
1: "o",
2: "g",
length: 3
}
When .length
is called on a primitive string, the JavaScript engine converts the string to a String
object as shown above. It is then mutable, and you gain access to the many built-in methods attached to String
. Once the method has been resolved, the above wrapper object is discarded. The same applies to numbers and Booleans (it does not apply to null and undefined).
Here’s a breakdown of the work JavaScript does under the hood:
- Create a
String
wrapper object, equivalent to usingnew String()
. - Call the inherited
.length
method on theString
wrapper object. - Once the method is complete, the wrapper
String
object is discarded. - Return the mutated primitive string (if a method like
substr( )
is used).
Is Everything in JavaScript an Object?
Not quite. It might be more accurate to say something along the lines of everything in JavaScript can appear to behave like an object. Primitives like String
, boolean
, and number
can behave like objects thanks to JavaScript features called object-wrapping and autoboxing. I hope this helps!
Go ahead and answer false and collect your cash money!