DEV Community

Cover image for Is everything in JavaScript an Object?
mayankav
mayankav

Posted on

Is everything in JavaScript an Object?

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";
Enter fullscreen mode Exit fullscreen mode


or did you choose to go with

var myString = new String("That's my string");
Enter fullscreen mode Exit fullscreen mode


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"
Enter fullscreen mode Exit fullscreen mode
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:

  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.

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

Latest comments (18)

Collapse
 
frontwebdev profile image
frontwebdev • Edited

. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned to a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered. (from mdn)

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.

Collapse
 
lilithkarapetyan profile image
Lilit Karapetyan

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.

Collapse
 
mayankav profile image
mayankav

@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.

Collapse
 
peerreynders profile image
peerreynders

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.

MDN: primitive values:

All types except objects define immutable values (that is, values which can't be changed).

seems like a more straightforward explanation - i.e. nothing was changed in the first place - JavaScript just ignores the attempt of mutation.

Collapse
 
mayankav profile image
mayankav • Edited

@peerreynders Indeed. Thanks for taking out time to read :)

Collapse
 
ahmedgmurtaza profile image
Ahmed Murtaza

Well explained!

Collapse
 
mayankav profile image
mayankav

:)

Collapse
 
baenencalin profile image
Calin Baenen • Edited

Jokes on you, since everything except numbers and arrays are objects in every language! >:)

(I don't mean Object object, I mean "object" as in a container, like the result of a constructed struct, union, or class.)

(This was only partially relevant.)

Collapse
 
reardon85 profile image
Reardon85

How is a "char" in C an object? And how is a string an object but an array isn't an object?

Collapse
 
baenencalin profile image
Calin Baenen

This is an outdated view. I realized not every language is quite like how I described.
Anyway, I never claimed chars 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.

Collapse
 
baenencalin profile image
Calin Baenen • Edited

To explain how I think about an object, this is what I think of an object as:

type Person struct {
  name [2]string;
  age float32;
} // "Person" type.

p := Person {name: {"Calin", "Baenen"}, age: 14.8333}; // Person object.
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mayankav profile image
mayankav

@baenencalin Didn't get you man! In JavaScript, arrays infact are objects :)

Collapse
 
baenencalin profile image
Calin Baenen

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 or int32.

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.

Collapse
 
baenencalin profile image
Calin Baenen

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.)

Thread Thread
 
mayankav profile image
mayankav

@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.

Thread Thread
 
baenencalin profile image
Calin Baenen

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.")?

Some comments may only be visible to logged-in visitors. Sign in to view all comments.