Well well! The motivation for this post comes from my last post where I had a comment from one of my readers that I couldn't agree with. I was talking about functions and closures (also how closures work internally) 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 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?
let myString = "That's my string";
let yourString = new String("That's your string");
console.log(typeof myString); // outputs "string"
console.log(typeof yourString); // outputs "object"
//MDN says primitives and objects can SOMETIMES be interchangeably used
let yourBigString = yourString.toUpperCase();
console.log(yourBigString); // outputs "THAT'S YOUR STRING"
let myBigString = myString.toUpperCase();
console.log(myBigString); // outputs "THAT'S MY STRING"
Try this on codepen
Does that ring a bell? We do often use primitives and objects interchangeably because JavaScript makes it possible for 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 an 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.
You may have two question now:
- If this is taken care of internally, what may go wrong if we assume that everything in JavaScript is an Object?
- 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.
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". We probably know why they say "most situations" and not "always".
Originally Posted Here -
https://mayankav.webflow.io/blog/is-everything-in-javascript-an-object
Top comments (18)
Jokes on you, since everything except numbers and arrays are objects in every language! >:)(I don't meanObject
object, I mean "object" as in a container, like the result of a constructed struct, union, or class.)(This was only partially relevant.)To explain how I think about an object, this is what I think of an object as:
@baenencalin Didn't get you man! In JavaScript, arrays infact are objects :)
To add clarity, strings are a little in the gray area.
If you're using a language like Go, if we disregard the built-in string type, they may be an array, or they may be a struct type, or they may be a wrapper type for an array, which would be an array of numbers, say
int16
orint32
.Of course, to be fair, we should consider the built in type - though, how it's built is dependent on the language.
In Java, it's definitely an object, both in the
Object
sense, and the sense that they are the result of a data structure.What I'm saying in most languages, like C, Go, C++, etc..
Everything except arrays and numbers are objects.
(I guess this isn't necessarily true for JS.)
@baenencalin Hey man! I get you now. I am not sure about all the other languages but what I can say is that its indeed a choice made by the langauge itself. I mean how a langauge defines primitives and objects is completely upto the language. We do have an article of faith on the universal notion though.
I thought primitives did have a definite definition ("The least abstract(ed) type in a given language. - Usually that who's implementation is the most bare-bones (compared to other types) when looking at the source code for a given language.")?
How is a "char" in C an object? And how is a string an object but an array isn't an object?
This is an outdated view. I realized not every language is quite like how I described.
Anyway, I never claimed
char
s were an object (even if they weren't listed as one ov the things that isn't an object); on the note ov arrays and strings, however, I don't consider arrays an object because they're usually just a consecutive arrangement ov data (in C it's literally just a pointer to said arrangement).I hope this answered your questions thoroughly; feel free to write back if you have any more questions.
MDN: primitive values:
seems like a more straightforward explanation - i.e. nothing was changed in the first place - JavaScript just ignores the attempt of mutation.
@peerreynders Indeed. Thanks for taking out time to read :)
Thank you for bringing up this topic. I heard that phrase so much that it was confusing me at the beginning of my career.
I think this myth was created by the people working in other languages who started to get acquainted with JS just a little bit :)
I don't think it is even possible for the language to only have objects as its type (Correct me if I'm wrong).
The most important note here was about the optimization part. Please, please, do not try to do these kinds of micro-optimizations yourself :) The browser engines are designed to detect and optimize all the "normal" code flows. If you try to do some weird things, the browser engine will not detect recognizable patterns and will fail to optimize the performance.
@lilithkarapetyan Hello Lilit! To answer your question, I'd say it completely depends on how a particular language defines primitives and objects. In JS, objects are nothing more than collective key:value pairs and anything that is not an object is a primitive. Consider another language, maybe 'C', it maps primitive types much closer to the underlying microprocessor architecture (int, char etc..). Generally in computer science "primitives" emply atomic types but then every programming language can freely decide on how to implement their own basic building block. For example Python chose to keep objects at the atomic level. So yeah, it depends on the language.
and you confused it.
when you write let str = 'hello' str is not primitive.
now try Object.isExtensible(str) you will get false and that a reason why you cannot add new prop to variable str.
Well explained!
:)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.