Object Prototypes Js Notes
Object Prototypes Js Notes
[Link]
Objects and Prototypes In-depth 17/01/2025, 00:17
Comprehensive notes on the JavaScript Objects and Prototypes In-depth series by Java Brains. This
resource dives deep into JavaScript's core concepts, including objects, prototypes, inheritance, and the
prototype chain, with clear explanations and practical examples. Perfect for mastering the foundations
of JavaScript object-oriented programming!
📺 Watch on YouTube
Highlights
02 - Objects Basics
JavaScript objects are collections of values, allowing for flexible structures and properties. They can be
created in various ways, including inline.
Highlights
03 - Creating Objects
Over here we learnt how to create employee objects with properties such as firstName, lastName, gender,
and designation.
const emp1 = { 1 / 19
firstName: "John",
lastName: "Doe",
[Link]
gender: "Male", 17/01/2025, 00:17
designation: "Software Engineer",
};
const emp2 = {
firstName: "Jane",
lastName: "Smith",
gender: "Female",
designation: "Project Manager",
};
However, manually creating multiple employee objects could quickly become repetitive and inefficient.
To address this, let’s introduce a reusable function called createEmployeeObject, which accepts parameters
for each property and dynamically generates employee objects.
return newObj;
}
This approach avoids the redundancy of manually defining each object, as shown in the earlier examples of
emp1 and emp2, and allows to efficiently create additional employee objects like emp3. By leveraging this
function, one can streamline object creation, reduce errors, and improve code maintainability in scenarios
involving multiple similar objects.
04 - JavaScript Constructors
Constructor functions in JavaScript simplify object creation by eliminating repetitive code, allowing developers
to use the new keyword for efficient object initialization.
return newObj;
}
2 / 19
The process of creating and returning a new object (var newObj = {} and return newObj) is repetitive when
[Link]
writing multiple functions to create different types of objects. JavaScript simplifies this using17/01/2025, 00:17
a constructor
function, which is called with the new keyword. Unlike other languages where the new keyword is used with a
class name, in JavaScript, it is used with a function. The new keyword automates the creation of a new object
and assigns it to this, making it available within the function. Behind the scenes, JavaScript essentially does
the following:
The commented lines (var this = {} and return this) represent the implicit actions performed by
JavaScript when a constructor function is invoked using new. This eliminates the need to explicitly create and
return the object, streamlining object creation in the codebase.
Highlights
We also have, bicycleConstructor, which simplifies object creation. By using the new keyword, JavaScript
automatically initializes a new object, binds it to this, and returns it implicitly. The function defines properties
3 / 19 and return statements.
directly on this, avoiding the need for explicit initialization
[Link] 17/01/2025, 00:17
function bicycleConstructor(cadence, speed, gear) {
[Link] = cadence;
[Link] = speed;
[Link] = gear;
}
Although JavaScript lacks explicit markers for constructor functions, the naming convention of starting
function names with a capital letter i.e. PascalCase (e.g., BicycleConstructor) serves as a visual cue for their
intended use. Additionally, the segment compares JavaScript's constructors to the class-based syntax in other
languages and hints at potential pitfalls when constructors are used improperly, setting the stage for future
discussions.
💡 Note: If you try to call a constructor function without new keyword, it will not work.
Constructor functions in JavaScript are specifically designed to be called with the new keyword, which
automates the creation of a new object, binds it to this, and implicitly returns it. In contrast, regular
functions can create objects without the need for new. However, using the new keyword with a regular
function can lead to unnecessary code execution and inefficiencies.
When a constructor function is called without the new keyword, JavaScript does not automatically create or
return an object, which often results in the function returning undefined. This happens because JavaScript
defaults to returning undefined when no explicit return statement is provided. On execution of constructor
function without new keyword, this keyword will refer to global window and the properties will be assigned to
global window object. This behavior underscores the importance of correctly distinguishing between regular
functions and constructor functions.
Mixing these function types without adhering to conventions, such as capitalizing constructor function names,
can lead to unexpected behaviors, errors, and confusion in the codebase. Following established naming
conventions and usage patterns helps ensure clarity, proper function usage, and maintainable code.
• 🧠 Direct Function Call: Calling a function directly executes it in the global context or the local context if
inside another function. This is the simplest form of function invocation.
• 🧠 Method Invocation: When a function is called as a property of an object, it executes in the context of
that object, allowing access to its properties through this. This distinction is important for object-oriented
programming in JavaScript. 4 / 19
• 🧠 Constructor Invocation: Using the new keyword creates a new object, and this within that function
[Link] 17/01/2025, 00:17
refers to the newly created object. This is fundamental for creating instances of objects.
Highlights
🌍 Execution context defines how functions are called and their environment.
📚 this is an implicit argument in JavaScript function executions.
🔍 Different methods of function calls affect the value of this.
🐢 Calling a function directly sets this to the global object.
📦 Using an object method sets this to the object itself.
✨ The new keyword creates a new object, with this referring to that object.
⚠️ Method 4 will explore practical use cases for this.
Key Insights
🌐 Execution Context: Every function call in JavaScript occurs within a specific context that includes variables
and scope information, essential for proper execution. Understanding this context is crucial for debugging and
writing effective code.
🔗 The this Keyword: This keyword behaves differently based on how a function is called, making it a pivotal
concept for JavaScript developers. Knowledge of this is vital for object-oriented programming in JavaScript.
🎯 Direct Function Calls: When a function is invoked directly (e.g., func()), this points to the global object,
which highlights how context can vary widely between environments (browser vs. [Link]).
🏷️ Method Calls: When a function is called as a property of an object (e.g., [Link]()), this refers to that
object. This showcases how object-oriented principles manifest in JavaScript.
🆕 Constructor Functions: Using the new keyword creates a new instance where this refers to the newly
created object, illustrating JavaScript’s prototypal inheritance
5 / 19
model.
🔄 Method Variability: The value of this is predictable based on the function invocation method, making it
[Link] 17/01/2025, 00:17
easier to anticipate behavior and avoid bugs in code.
⚡ Next Steps: Understanding the fourth method of function calls and practical applications of this is essential
for mastering JavaScript’s execution context and resolving common issues related to scope.
Over here the Bicycle constructor function demonstrates how objects in JavaScript can have properties and
methods that operate within the context of the object they belong to. The inflateTires method is a
particularly important example because it highlights how the this keyword works in JavaScript and how it
enables the modification of object-specific properties.
When a new Bicycle instance is created using the Bicycle constructor function, the this keyword inside the
function refers to the newly created object. For example, when bicycle1 is instantiated using the new
Bicycle(50, 20, 4, 25) call, this in the constructor points to bicycle1. The constructor assigns the passed
values to the object's properties (cadence, speed, gear, and tirePressure) and defines the inflateTires
method directly on the object.
The inflateTires method uses [Link] to access and modify the tirePressure property of the
object it is called on. When the method is invoked on an instance, such as [Link](), the
this keyword inside the method dynamically refers to the bicycle1 instance. This is a crucial feature of
JavaScript's this behavior: its value is determined by the object that calls the method.
[Link]();
[Link]([Link]); // Output: 28
Here, calling [Link]() increases bicycle1's tirePressure by 3, because the this keyword
inside the method specifically refers to the bicycle1 instance. If the method were called on a different object
(e.g., another Bicycle instance), this would refer to that object, and only its tirePressure would be
updated.
6 / 19
This behavior demonstrates how JavaScript allows methods to operate within the scope of the object they
[Link] 17/01/2025, 00:17
belong to, providing a powerful way to manage object-specific data. By using the this keyword, methods like
inflateTires can dynamically adapt to the context of the object they are called on, ensuring that changes
are made only to the relevant instance. This encapsulation of behavior and data is fundamental to object-
oriented programming in JavaScript.
Code Explanation:
1. Bicycle Constructor: A Bicycle constructor function is defined, allowing the creation of bicycle objects
with properties like cadence, speed, gear, and tirePressure. Each Bicycle instance has an
inflateTires method that increases the tirePressure by 3, using [Link] to refer to the
specific object it is called on.
2. Mechanic Constructor: A Mechanic constructor function is used to create mechanic objects with a name
property. In this example, a mechanic named "Mike" is created.
3. Method Borrowing: The inflateTires method from the bicycle1 object is assigned to the Mechanic
instance mike. However, when [Link]() is invoked, the this keyword inside the method
refers to the mike object, which does not have a tirePressure property. This results in an error or an
invalid operation (e.g., [Link] += 3 will produce NaN because undefined + 3 is not a valid
operation).
To address this, we need to ensure that the this keyword inside the inflateTires method refers to the
correct object (e.g., a Bicycle instance). This can be done in two ways:
Code:
// Bicycle constructor
function Bicycle(cadence, speed, gear, tirePressure) {
[Link] = cadence;
[Link] = speed;
[Link] = gear;
[Link] = tirePressure;
[Link] = function () {
[Link] += 3; // This assumes 'this' points to a Bicycle object.
};
}
// Mechanic constructor
7 / 19
function Mechanic(name) {
[Link] = name;
}[Link] 17/01/2025, 00:17
// Creating objects
var bicycle1 = new Bicycle(50, 20, 4, 25);
var mike = new Mechanic("Mike");
Key Insights:
Understanding this: The this keyword refers to the calling object, not the object where the method
is defined. This can lead to errors when borrowing methods.
Managing Context: Using call, apply, or bind allows you to explicitly set the value of this, ensuring
that methods behave as expected.
Modular Functions: Methods like inflateTires can be adapted for reuse by passing the required
object as an argument or binding the correct context at runtime.
Error Prevention: Without proper management of this, operations can lead to invalid results, such as
attempting to modify properties that do not exist on the calling object.
This example underscores the flexibility and challenges of working with this in JavaScript, encouraging
developers to pay close attention to context when reusing or borrowing methods.
Unit 03 - Prototypes
11 - When constructors aren't good enough
Prototypes in JavaScript allow you to create objects based on a shared template or blueprint.
Unlike class-based programming languages (e.g., Java, C++), JavaScript doesn't have classes (at least
before ES6). Instead, it uses prototypes to define reusable behaviors across objects.
While prototypes aren't exactly like classes, they serve a similar purpose by enabling objects to share
behaviors without duplicating them.
In languages like Java or C++, objects are instances of classes, and these classes act as the blueprint
for the objects.
In such languages:
You cannot create objects "out of thin air."
8 /Every
19 object must be an instance of a class.
Methods (functions) are shared across all instances of a class. The methods are defined once in
[Link] 17/01/2025, 00:17
the class and reused by all instances, saving memory.
In contrast, JavaScript:
Does not enforce class-based object creation. Objects can be created independently without
needing a "class."
Does not inherently distinguish between "properties" and "methods." In JavaScript:
Objects have properties, which can store values (primitive types, objects, or functions).
A function property may behave like a "method," but it is not inherently tied to a class or
the object in a traditional sense.
JavaScript uses constructor functions to create objects with shared properties and methods.
Drawback:
If you have a large number of objects (e.g., 1,000 employees in an employee management system),
each object will unnecessarily have its own copy of methods, leading to memory inefficiency.
This is wasteful because the logic of methods (like inflateTires) remains the same for all instances.
Note: There is a new class keyword in the newer version of JavaScript(ES6) that simulates class-like
behaviour, but JavaScript does not have the class concept.
The JavaScript engine creates a prototype object for every function, even if the function does
nothing (e.g., empty functions like function foo() {}).
This prototype object is associated with the function via its prototype property.
When a function is called with the new keyword, the JavaScript engine:
1. Creates a new object.
2. Executes the function, setting this to the new object.
3. Links the new object to the prototype object of the function.
The resulting object has a special property, __proto__, which points to the function's prototype
object.
The __proto__ property is automatically added to any object created using the new keyword.
It links the new object to the prototype object of the function.
All objects created using the same function share the same prototype object.
If the function is called without new, the prototype object is not used.
If the function is called with new, the new object references the prototype object via __proto__.
7. Key Observations:
Functions that do not involve object creation still have a prototype object, but it is unused unless
the new keyword is used.
Objects created using the new keyword share a single prototype object, ensuring efficient memory
usage.
These steps are fundamental for understanding how JavaScript utilizes prototypes to manage object behavior
and inheritance. The significance of the prototype object
10 / 19and the __proto__ property will become clearer in
subsequent lessons.
[Link] 17/01/2025, 00:17
When a function (e.g., function Foo) is created, its .prototype property refers to the prototype
object associated with the function.
Objects created using the new keyword (e.g., let obj = new Foo()) contain a special __proto__
property that points to the function’s .prototype object.
You can validate this by setting a property on the .prototype object (e.g., [Link] =
"prototype property"), which becomes accessible via obj.__proto__.test or
[Link].
If a property exists on the object itself, the prototype object is not consulted. For example:
Setting [Link] = 10 overrides the prototype’s test property.
Accessing [Link] returns 10, not the value from the prototype.
Deleting the property on the object (e.g., delete [Link]) re-enables access to the prototype’s
test property.
Practical Example:
This lookup mechanism is implicit and transparent, making it difficult to tell if a property is from the
object or the prototype without explicitly examining the object.
To check explicitly:
This allows JavaScript to create shared behavior across objects (like a blueprint or template). Instead of
duplicating methods and properties for every instance, shared behaviors reside in the prototype. More on this
will be explored in future lessons!
Prototype lookup enables shared behavior across multiple objects created from the same constructor
function.
Objects created using a constructor share the same prototype.
This avoids duplication of properties/methods for each object, saving memory.
Objects created using the new keyword inherit from the constructor’s .prototype. Example: Constructor with
a Prototype
function Employee(name) {
[Link] = name; // Instance-specific property
}
// Create objects
const emp1 = new Employee("Jim");
const emp2 = new Employee("Pam");
---------------------------------------------------------------
// Efficient Method Definition:
function Employee(name) {
[Link] = name;
}
[Link] = function () {
[Link]("Prank played!");
};
Prototype properties/methods can be added at runtime, and all existing objects will immediately
inherit them.
1. Dynamic Runtime Lookup: Prototype properties are checked at runtime, so changes to the prototype
are immediately reflected on all objects.
2. Shared Behavior: Shared methods reduce memory usage and simplify updates.
3. No Need for Upfront Definition: Unlike class-based languages, prototype methods can be added
13 / 19
dynamically after object creation.
4. In traditional class-based languages, all behaviors must be defined upfront before object creation.
[Link] 17/01/2025, 00:17
In JavaScript, objects and functions are connected via a network of prototype relationships that allow
behavior sharing and object creation. Here's how it works:
When a function is created, it gets a special property called prototype that points to a prototype
object:
function Foo() {}
[Link]([Link]); // Prototype object
When an object is created using the new keyword, the object gets a special property __proto__ (also
called "Dunder Proto"), which links it to the function's prototype:
The prototype object itself has a constructor property that points back to the function:
[Link] = function () {
[Link]("Hello!");
};
[Link](); // "Hello!"
// If the object (a) doesn’t have a property or method, JavaScript looks up the chain to
__proto__ (i.e., the prototype) to find it.
When defining shared behavior, always use the constructor’s prototype property:
[Link] = function () {
[Link]("Hello from Foo!");
};
The Object function in JavaScript is both a global function and an object. It acts as a global constructor
function that allows you to create objects. For example:
Both approaches are equivalent. {} is simply a shorthand for new Object(). To prove this, you can check the
prototype chain:
When you create an object using {}, JavaScript internally calls new Object() behind the scenes.
3. The __proto__ property of the created object (e.g., emp) points to the Employee's prototype.
15 / 19
4. The prototype object for a constructor (e.g., [Link]) is itself created by calling new
[Link] 17/01/2025, 00:17
Object(). This means the __proto__ of [Link] points to [Link].
5. Properties can be added to prototypes at any level, making them accessible to all instances:
Adding to [Link]:
Adding properties to [Link] affects all objects in JavaScript because every object's
prototype chain ends at [Link].
Caution: This is similar to using global variables and should be avoided in large systems to
prevent conflicts.
The [Link] itself has a __proto__ that points to null.
This is the end of the prototype chain, preventing infinite loops during property lookups.
[Link]([Link].__proto__); // null
// Instance → Constructor's Prototype → [Link] → null.
18 - Inheritance In JavaScript 16 / 19
In JavaScript, inheritance is achieved via the prototype chain, allowing objects to inherit properties and
[Link] 17/01/2025, 00:17
methods from other objects. This example demonstrates how to implement multi-level inheritance using
JavaScript's prototype system.
Prototype Chain: Every function in JavaScript has a prototype property, and instances created using
that function inherit methods and properties from the function’s prototype.
Setting the Prototype: By modifying the __proto__ property, we can change the prototype chain to
share behaviors between different constructors (e.g., Employee and Manager).
17 / 19
Prototype chain before linking Employee and Manager:
[Link] 17/01/2025, 00:17
18 / 19
Prototype chain after linking Employee and Manager:
[Link] 17/01/2025, 00:17
This concept is the foundation of object-oriented programming in JavaScript and can be extended further to
create deep inheritance hierarchies.
Thank you!
19 / 19