How Everything in JavaScript is an Object

Table of contents
- [[Prototype]] in JavaScript
- __proto__ in JavaScript
- .getPrototypeOf and .setPrototypeOf
- Constructor Functions
- Classes: Syntactic sugar for constructor functions
- Dot Prototype Property
- Working of: The new keyword
- Simple Summary of: [[Prototype]] vs __proto__ vs .prototype
- Prototypal Inheritance and Reason for "Everything is Object in JS"
- Conclusion

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
andPersonConstructor
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 prototypeExecutes 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!
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