Understanding call and this in JavaScript

I believe the best way to master a concept is to explain it to someone else. I’m a Full Stack Developer navigating the ecosystems of JavaScript and Python, building everything from responsive frontends to robust backends. I use this space to document my learning journey, break down complex topics, and share practical solutions to the bugs I encounter. Let's learn in public together!
In JavaScript, the this keyword provides a reference to the current execution context. However, when functions are nested, determining the correct this context can be challenging. Let’s explore this concept with a detailed example.
Nested Functions and this Context
Consider a scenario where a function is called within another function:
function outerFunction() {
innerFunction();
}
In this example, innerFunction doesn't have a clear reference to this within outerFunction. Here's a visualization of the call stack:

and below callMe(), we have an execution context of the parent function.
In such cases, this typically refers to the Global Execution Context (GEC). In a browser environment, this means the window object, while in a Node.js environment, it refers to an empty object.
Example: Setting User Details
Let's see how this works in practice:
function setUsername(username) {
this.username = username;
console.log("called");
}
function createUser(username, email, password) {
setUsername(username);
this.email = email;
this.password = password;
}
const chai = new createUser("chai", "chai@fb.com", "123");
console.log(chai);
//outputs: createUser { email: 'chai@fb.com', password: '123' }
Notice that the username property is missing. This occurs because setUsername is called without a proper this context, causing it to refer to the GEC.
Also, the function is getting called, but after the function has done its work, it gets out of the call stack and the memory is released, Also we have given a reference to the function, now you will think that "setUsername(username)" is a function call in itself, but it's only the reference.

Therefore, in JS we get some methods through which we can explicitly call the functions, and one of those methods is "call".
Now if we only use "call", then output will be the same as earlier, as after the function has done its work, it gets out of the call stack and memory is released, therefore we don't get that variable inside the parent function.
Therefore we have to hold the reference and for this purpose, we can use "call" for explicitly calling and holding the reference.
Now, we also have to pass execution context, as we are saying to the child function that don't use your "this" as it is going to be released.
But use my "this" i.e of parent function, therefore we have written it like "setUsername.call(this, username)"
Explicitly Setting this with call
To resolve this issue, we can use the call method to explicitly set the this context of setUsername:
function setUsername(username) {
this.username = username;
console.log("called");
}
function createUser(username, email, password) {
setUsername.call(this, username);
this.email = email;
this.password = password;
}
const chai = new createUser("chai", "chai@fb.com", "123");
console.log(chai);
//outputs:
called
createUser { username: 'chai', email: 'chai@fb.com', password: '123' }
By using "setUsername(this, username)", we ensure that setUsername uses the this context of createUser.
Significance of "new" keyword:
Object Creation: The
newkeyword creates a new empty object.Prototype Linking: The new object's prototype is set to
createUser.prototype.Context (
this): Thethiscontext insidecreateUseris bound to the new object.SetUsername Call:
SetUsername.call(this, username)sets theusernameproperty on the new object.Property Setting:
this.emailandthis.passwordare set on the new object.Implicit Return: If no object is explicitly returned, the newly created object is returned.
Assignment: Therefore,
chaiis assigned the new object with the propertiesusername,email, andpassword.
Key Points to Remember
Global Execution Context (GEC): In a browser,
thisrefers to thewindowobject. In Node.js, it refers to an empty object.Function Calls: When a function is called inside another function,
thismay not refer to the intended context.Using
call: Thecallmethod can explicitly setthisfor a function, ensuring it uses the correct context.
Understanding and using call effectively allows us to manage this context accurately, ensuring our functions behave as expected.




