this confuses candidates because its value usually depends on how a function is called, not where that function was written. If you learn only the obj.method() case, detached methods, callbacks, and arrows all look unpredictable. A small precedence rule makes their output traceable.
The four this-binding rules, by precedence
For ordinary functions, inspect the call site and apply the highest matching rule:
newbinding: A constructor call creates a fresh object and uses it asthis.Explicit binding:
call,apply, orbindsuppliesthisdirectly.Implicit binding: In
obj.method(), the object immediately before the dot isthis.Default binding: A bare
fn()call hasthis === undefinedin strict mode. In a classic non-strict browser script, it can fall back to the global object.
Arrow functions sit outside this ladder. They do not create their own this; they inherit it from the surrounding lexical scope. call, apply, bind, and new cannot assign an arrow its own receiver.

When rules appear to compete, precedence resolves the result. A bound ordinary function called with new uses the fresh constructed object, while an explicit call overrides an object that might otherwise provide implicit binding.
One reliable interview habit is to ignore the definition site first. Rewrite the final invocation alone, identify its call syntax, and only then inspect the function body.
Implicit binding and the lost-this trap
Start with a method call:
const obj = {
x: 10,
get() {
return this.x;
}
};
obj.get(); // 10The call site is obj.get(), so implicit binding makes this equal to obj.
Now detach the same function:
const g = obj.get;
g();The call site is now a bare g(). In strict mode, this is undefined, so trying to read this.x throws a TypeError. In a sloppy browser script, this may be window; if window.x is absent, the expression returns undefined. The method did not remember obj. Passing an unbound method as a callback creates the same lost-receiver problem.
Explicit binding with call, apply and bind
All three APIs select a receiver for an ordinary function. Their difference is how arguments arrive and whether invocation happens now.
function greet(greeting) {
return greeting + " " + this.name;
}
const person = { name: "Asha" };call invokes immediately and accepts arguments one by one:
greet.call(person, "Hi"); // "Hi Asha"apply invokes immediately but accepts the arguments in an array-like collection:
greet.apply(person, ["Hi"]); // "Hi Asha"bind does not invoke immediately. It returns a new function whose receiver is fixed:
const boundGreet = greet.bind(person);
boundGreet("Hi"); // "Hi Asha"The calculation in every case is the same: this.name contributes "Asha", so "Hi" + " " + "Asha" produces "Hi Asha". bind is especially useful when handing a method to code that will later make a bare callback call.
Remember that bind returns a new function. It does not modify greet, and later calling the original still follows its own call site.
Arrow functions use lexical this
An arrow captures this from the surrounding scope where the arrow is created. That is useful for a callback nested inside a correctly called method:
const timer = {
seconds: 0,
start() {
setInterval(() => {
this.seconds++;
}, 1000);
}
};
timer.start();timer.start() gives the ordinary start method implicit binding, so this inside start is timer. The arrow then closes over that same value. Each interval callback adds 1 to timer.seconds; after one callback it is 1, after two it is 2, and after three it is 3.
A regular function callback would receive its this according to how the timer system invokes it, not from start. Do not assume that receiver is timer.
Lexical capture has a flip side. An arrow is usually the wrong choice for an object method that needs the object as its receiver:
const user = {
name: "Asha",
getName: () => this.name
};user.getName() does not make the arrow's this equal to user. The arrow keeps the outer this. The same warning applies to prototype methods. Use ordinary method syntax when the call site should select the receiver.
new binding creates the receiver
Constructor-style calls apply the highest rule:
function Person(name) {
this.name = name;
}
const p = new Person("Asha");
p.name; // "Asha"new creates an object linked to Person.prototype, binds it as this, runs the function, and normally returns that object. Calling Person("Asha") without new is a bare call instead. In strict mode, assigning this.name then throws because this is undefined; sloppy code can accidentally write a global property.
Modern code can use a class when construction is intended, but interviews still use constructor functions to test whether new changes the receiver.
Interview traps involving this
A detached method loses implicit binding.
A nested regular function inside a method gets its own receiver from its own call site.
setTimeout(obj.method, 0)passes a function, not anobj.method()call. Bind it or wrap it in an arrow that calls the method.Event systems may deliberately set
thisto an element or another dispatcher-specific value. Check that API rather than assuming your object.An arrow used as a method does not acquire the object receiver.
callorapplyon an arrow can pass arguments but cannot replace its lexicalthis.Rebinding an already bound function does not replace the receiver fixed by the first
bind.
The setTimeout case is worth tracing once, because the fix depends on which receiver you want:
const counter = {
n: 5,
show() {
console.log(this.n);
}
};
setTimeout(counter.show, 0); // undefined
setTimeout(() => counter.show(), 0); // 5
setTimeout(counter.show.bind(counter), 0); // 5The first line hands show to the timer as a plain function value, so the timer chooses the receiver. Host environments differ on what they pass (a browser supplies the global object, Node supplies its own timer object) and neither carries an n property, so this.n reads undefined. The arrow keeps the real call site as counter.show(), and bind fixes the receiver before the timer ever sees the function, so both of those print 5.
Practise these output patterns alongside JavaScript interview questions for freshers and React interview questions for freshers. React class callbacks and ordinary JavaScript methods expose the same call-site principle.
The short version and next step
For an ordinary function, find the call site and apply new, explicit, implicit, or default binding in that order. Arrows instead inherit this lexically. call and apply invoke now, while bind returns a fixed function for later.
Two habits carry most of the marks here: name the rule you applied, and say what happens in strict mode as well as in a sloppy script. Use the Placement Preparation category for the broader route, build the language model in Complete JavaScript, or follow the Mera Placement Hoga bundle. On each snippet, circle the call site before predicting the output.




