Is everything in JavaScript an Object?

Mayank
|
July 6, 2021

Well well! The motivation for this post comes from my last post where I secured a comment from one of my readers that I couldn't agree with. I was talking about functions and closures and how every function in JavaScript is indeed a closure on its surrouding scope but then somebody said, aren't all entities in JavaScript objects? I didn't see that coming but this wasn't the first time somebody put this up. So you will find me trying to break this down practically in this post.

If you can, bring up your browser's console and try creating a simple variable and give it a string value. How did you do it? Did you write something like var myString = "That's my string"; or did you choose to go with var myString = new String("That's my string"); For a fact, I know you didn't choose the last method. I mean no body does and if you want to prove me wrong and say that you did infact choose the second one, well somebody will then probably ask you, why? MDN says "String primitives and string objects can be used interchangeably in most situations". MDN then also says "a Primitive (primitive value, primitive data type) is data that is not an Object". The second statement makes the answer clear "Not everything in JavaScript is an Object" and this can easily be verified by using the "typeof operator". We still need to clarify the pin size difference. With an example?

Try this on codepen

Does that ring a bell? We do often use primitives and objects interchangeably because JavaScript makes it possible for immutable primitives to somehow use the methods designed into real Objects. Using a primitve value shall give you the benefit of writing concise without losing on the comfort of using easy methods to manipulate and process the values. When you call a String object's method on a primitive string value, to make this work your primitve is first wrapped into the appropriate Wrapper class (String in this case). The method you want to call is called on the transient object which is discarded as soon as the result is returned. Read on MDN. The following codepen shall present a demo.

Try this on codepen

You may have two question now:

1 - If this is taken care of internally, what may go wrong if we assume that everything in JavaScript is an Object?

2 - If the JS engine does this autoboxing internally everytime we use a primitive, isn't this more expensive than simply using String Objects?

To answer the first question, let me throw another example which is an extension to the very first example. The example shows a case where someone would try assigning a property to some primitive expecting it to be retrievable. If you assign some property to a string primitive with an intention of getting the value back at some point, you will only be returned 'undefined' because the temporary String Object was discarded then and there. Similarly such assumptions can misfire when using eval (which indeed should not be used). These examples may not be very relatable but I guess they are enough to warn us from assumptions.

Try this on codepen

I believe the second question is no less important. Even though this seems like a tedious process of coercing a primitive into an Object and then calling the method on the temporary object, the JavaScript engine highly optimizes this process. It may even skip the creation of the extra object altogether. If you still wonder why do we even have primitives, you better ask Brendan Eich as T.J Crowder says in this answer.

Conclusion

To conclude I'd just highlight that MDN says "String primitives and string objects can be used interchangeably in most situations". Now we know why they say "most situations" and not "always".

written by
Mayank
Web Technology Enthusiast