How Everything in JavaScript is an Object

RohitRohit
8 min read

If you have been learning JavaScript, you would have surely come across this statement: "Everything in JS is an Object" once or twice. But have you ever wondered why and how this happens?

If you have been curious enough, you might have an idea of Prototypes and the Prototypal nature of JS—the reason behind the statement.

But what actually are prototypes and how does it justify the given statement? In the blog below, we will go through the Prototypal nature of JavaScript and how it justifies the statement "Everything in JS is an Object".

[[Prototype]] in JavaScript

Going back to the roots, JavaScript was natively invented to make websites dynamic. The concept of objects existed before JavaScript in many other languages, but the way JavaScript implemented objects and their nature was quite interesting.

You wouldn't believe, but JavaScript was developed by Brendan Eich within just 10 days.

If you have ever played with objects in a browser, you might have noticed a property called [[Prototype]] attached to every object you create.

The property name for [[Prototype]] can differ depending on the browser, as different JavaScript engines may implement it differently.

This [[Prototype]] is an internal property, responsible for all the methods you get to use in objects. Every derived datatype where you can use methods has the [[Prototype]] property attached to it. You can see this in arrays too.

So, [[Prototype]] is the property internally given by the JavaScript engine itself to the derived data types for the usage of methods attached to it.

__proto__ in JavaScript

But the catch here is you cannot modify the [[Prototype]] property of any object directly. You are not given access to it.

Here is where __proto__ comes into the picture. __proto__ acts like a getter and setter for the [[Prototype]] property of objects. But this feature is not the standard for JavaScript as set by ECMAScript, the organization that sets JS standards. The __proto__ is a legacy feature, part of the Annex B feature of JavaScript.

Annex B is a list of features that are not standardized but still exist.

.getPrototypeOf and .setPrototypeOf

Since __proto__ started being heavily used by developers, it was crucial to standardize its use. Hence, ECMAScript introduced the .getPrototypeOf and .setPrototypeOf methods as the standard getter and setter for the [[Prototype]] property.

Constructor Functions

Constructor functions are used to construct other objects. You can understand this as the cookie cutter that is used to cut all of your cookies into a similar shape and size. While you cannot technically eat this cookie cutter itself, you can use it to make something you can eat.

Similar to the analogy, you cannot use the constructor function itself, but it acts as a blueprint to give the shape and size (i.e., properties and methods) to other functions and objects.

Below is an example of a constructor function:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Constructor function names start with a capital letter, and this is considered a convention. It indicates that the function is a constructor and not a regular function. This convention is also related to the class naming convention in JavaScript

Now that you understand constructor functions, let us look at a newer version of creating the constructor functions and reusing them to define the shape and size of other objects.

Classes: Syntactic sugar for constructor functions

Class are the fundamental concept behind the Object Oriented Programming (OOP) programming paradigm. They are blueprints defined for objects.

They help organize the code and maintain it's readability and exists in many languages like java and C++.

Similar to how we have an structural layout of any building before actually building it, we have class as an structural layout for the objects to form from it.

Coming back to JavaScript, before classes we used to use constructor functions to build the blueprint aka structural layout for objects. But since class was a very common pattern and even existed in legacy languages like C++ and Java, JavaScript introduced the concept of classes and standardized it in its ES6 version (ECMAScript Version 6). They are nothing but a Syntactic sugar to constructor functions. Following is an example of the way we created blueprint, before and after ES6 classes

Example: Constructor Function and Class (Before and After ES6)

Before ES6, we used constructor functions to create and reuse blueprints for objects. With ES6, we now have a more familiar syntax—classes. Here is how we can achieve the same thing using a class and a constructor function:

Both the Person constructor function and the Person class do the same thing. They define the shape (properties) of the objects that are created with them. The difference is just syntactic—the class syntax is cleaner and more familiar to developers coming from languages like Java and C++.

But wait, Rohit, how can you say that they're the same? You might ask for proof. Well, let's take a look at some proof. Let’s create a similar PersonClass and PersonConstructor with same properties and check out what they contain.

Aren’t they quite similar? Yes, the things differ a bit since the internal implementation of classes is more optimized than constructors, also it’s newer.

NOTE: console.dir is used to display an interactive list of an object's properties.

Dot Prototype Property

If you observed the above output carefully, you might have noticed a property called prototype in both of them. But wait, what is this prototype?

The prototype is a property that holds the constructor function and the [[Prototype]] property of the class or the constructor function.

Rohit, I understand that it holds the [[Prototype]] property as it exists in all derived data types in JavaScript, but what about the constructor property ?

Well, the constructor property holds a reference to the constructor function or the class itself. But why, you might ask?

It’s there to inform both you and the JavaScript engine which constructor function or class created a new object. Also, it’s useful when you don't know which class or constructor function was used to create an object and you want to create a similar object to what you see. ( used in third party libraries )

It’s like a relative child saying "Mujhe bhi bhaiya wali laptop hi chahiye," when they don’t even know which brand it is or which model it is. And hence not the brand but you inform them about the brand and model of it.

Rohit, it’s becoming a bit confusing. Let me clarify with an example:

Now that you know what the `prototype` property contains, how do you change its `[[Prototype]]`?

Working of: The new keyword

You might have noticed the new keyword used to create objects in the above examples. So how does new work and what does it do ?

The new keyword is used to create new instances (objects) form constructor functions or classes. It plays significant role in object creation process and helps set up the prototype chain. Following things happen when you use new keyword:

  • New Empty object gets created

  • this is assigned as the newly created object

  • [[Prototype]] is set to the prototype of the constructor function or class, allowing it to access the methods and properties from prototype

  • Executes the constructor function

  • returns the object to the variable ( automatically )

Simple Summary of: [[Prototype]] vs __proto__ vs .prototype

Let us have a simple summary of what [[Prototype]], __proto__, and .prototype mean before proceeding ahead.

Try answering this yourself first:

  • [[Prototype]] is the internal property given by the JS engine to derived datatypes/objects.

  • Since you cannot access or change this property directly, you are given something called __proto__ that helps you get or set the property. But this isn't the standard (What is the standard?).

  • .prototype is a property given to constructor functions that holds an object containing the constructor function itself and the [[Prototype]] of that function.

Now that you are clear about it, let's proceed to the main question we started the blog with: Why is Everything in JS an Object?

Prototypal Inheritance and Reason for "Everything is Object in JS"

We know that everything in JS internally contains the [[Prototype]] property. But if we dig deeper and look further, the [[Prototype]] property, an object, also contains another [[Prototype]] in it. Don't believe me? Look at the following example of an array

So, what do you notice?

There is a chain of [[Prototype]] properties in anything created in JS that ends with the last [[Prototype]]: Object, because the [[Prototype]] in the object points to null. This is what we call Prototypal inheritance or Prototypal chaining in JavaScript and is the core reason behind why "Everything in JS is an Object", as the last [[Prototype]] in the chain points to Object.

Wait, Rohit, how does it make Everything if it's only the derived datatype? Does const num = 1 also have [[Prototype]] in them?" Well, JS internally converts primitives to corresponding wrapper classes (like String, Number) when necessary.

These wrapper classes and type coercion are behind behaviors like " " == 0 evaluating to true, which we'll cover more in-depth in the next part of this JS journey

Conclusion

In this blog, we explored the prototypal nature of JavaScript and how it justifies the statement "Everything in JS is an Object." We discussed the internal [[Prototype]] property that all objects have and how it enables inheritance through the prototype chain. We also covered the difference between [[Prototype]], __proto__, and .prototype, along with how constructor functions and ES6 classes provide blueprints for creating objects. By understanding these concepts, we see that everything in JavaScript is indeed an object, from arrays to primitive types, due to the prototype-based inheritance system.

In short, everything in JavaScript is connected through prototypes, making the language flexible and dynamic.

If this has sparked your curiosity, feel free to like the blog and subscribe to my newsletter. You'll get more insights like this delivered in an easy-to-understand format!

63
Subscribe to my newsletter

Read articles from Rohit directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rohit
Rohit

Just a curious child exploring tech