JavaScript this keyword interview questions, with answers
this is the JavaScript question that separates people who have read about functions from people who have debugged them. Its value is not fixed where a function is written; it is decided by how the function is called, and a handful of rules cover every case. Interviewers test those rules with a method passed as a callback, an arrow function inside a class, or a call, apply or bind, and ask what this refers to. Every output shown was produced by running the code in Node.js.
The questions start with the rules, then the ways this gets lost and kept, then classes and borrowed methods. Then take the free JavaScript diagnostic — ten questions across every JavaScript topic in the bank — to see which of these you can explain but not yet predict.
The questions, with answers
1.How is the value of this determined in JavaScript?
In short: By the call, not the definition: new sets it to the new object, call, apply and bind set it explicitly, obj.method() sets it to obj, and a plain call leaves it undefined in strict mode.
Check the rules in order of priority. A function called with new gets a fresh object as this. One called through call or apply, or created by bind, gets the object passed in. One called as a property, obj.method(), gets the object before the dot at the moment of the call. Anything else is a plain call, where this is undefined in strict mode, or the global object in sloppy scripts. Arrow functions sit outside the rules: they have no this of their own and use the this of the scope they were written in. The same function below gives two answers depending only on how it is called, and the rules explain this page's sample: a method stored in a variable and called plainly loses its object.
"use strict"; function who() { return this?.tag ?? "none"; } const o = { tag: "cart", who }; console.log(o.who()); // cart console.log(who()); // none
2.Why does this get lost when a method is passed as a callback?
In short: Passing obj.method passes the function alone, without obj, so whatever calls it later calls it plainly and this is undefined; bind the method or wrap it in an arrow function.
A method is just a function stored on an object, and the object is attached only by the call syntax obj.method(). Hand obj.method to setTimeout, addEventListener or an array's forEach, and whatever calls it later calls it as a plain function. In strict mode, which every class body uses, this is then undefined, and reading a property from it throws a TypeError, as the last line below does. Three fixes: pass obj.method.bind(obj); pass an arrow function, () => obj.method(), which calls it properly; or define the method as an arrow function in a class field, which captures the instance once, when it is constructed. This is the classic bug behind a class-component event handler that cannot reach its own state.
class Timer { secs = 5; show() { return this.secs; } } const t = new Timer(); const f = t.show.bind(t); console.log(f()); // 5 const g = t.show; g(); // throws TypeError
3.How do arrow functions handle this differently from regular functions?
In short: An arrow function has no this of its own: it uses the this of the code around it, fixed when the arrow is created, and call, apply or bind cannot change it.
Inside an arrow function, this means exactly what it means on the line where the arrow is written. That makes arrows the natural choice for callbacks inside methods, where an ordinary function would lose the method's this: the timer callback below still updates the instance that start was called on. The same property makes arrows wrong as object methods: an arrow written in an object literal takes this from the surrounding scope, not from the object. Arrows also have no arguments object and no prototype, and cannot be called with new. Passing a different this to an arrow through call, apply or bind is silently ignored.
class Clock { ticks = 0; start() { setTimeout(() => { this.ticks++; console.log(this.ticks); }, 0); } } new Clock().start(); // 1
4.What is the difference between call, apply and bind in JavaScript?
In short: call and apply invoke a function at once with a chosen this — call takes the arguments one by one, apply as an array — while bind returns a new function with this fixed for later.
All three set this explicitly. fn.call(obj, a, b) and fn.apply(obj, [a, b]) run fn immediately; the only difference is how the arguments are passed, and since spread syntax, fn.call(obj, ...args) has made apply mostly a matter of habit. bind(obj, ...args) runs nothing: it returns a new function whose this is fixed, optionally with leading arguments filled in, which is partial application, as fix shows below. A bound function cannot be re-bound to another object, and its bound this is ignored when it is called with new. On an arrow function none of the three can change this, because an arrow has none of its own to set.
function cost(tax) { return this.amt + tax; } const b = { amt: 200 }; console.log(cost.call(b, 36)); // 236 const r = cost.apply(b, [18]); console.log(r); // 218 const fix = cost.bind(b, 50); console.log(fix()); // 250
5.What does this refer to inside a JavaScript class and a static method?
In short: In instance methods and field initialisers this is the instance; in static methods and static fields it is the class itself; and class bodies always run in strict mode.
A class method called as obj.method() gets the instance, like any method, and loses it the same way when detached, with no fallback to the global object because class code is strict. Field initialisers run once per instance during construction, with this as the new instance, which is why an arrow function stored in a field keeps its instance for good. In a static method, called as ClassName.method(), this is the class, so new this() respects subclasses: below, make() is written once on Shape but builds a Sq when called on Sq. In a subclass constructor, this cannot be used until super() has been called; before that, touching it throws a ReferenceError.
class Shape { static make() { return new this(); } kind() { return "shape"; } } class Sq extends Shape { kind() { return "square"; } } console.log(Sq.make().kind()); // square
6.What does this refer to in a DOM event handler?
In short: In a listener written as an ordinary function, this is the element the listener was added to, the same as event.currentTarget; in an arrow-function listener, it is whatever this was outside.
addEventListener calls an ordinary function with this set to the element it was registered on, so one handler shared by many buttons can use this to act on whichever button was clicked. event.currentTarget gives the same element and works in arrow functions too, which is why modern code prefers it: an arrow handler inherits this from the surrounding code, often a class instance, which is useful when the handler needs the component rather than the element. Do not confuse currentTarget with event.target, the element where the event started, which may be a child of it. Inline HTML attributes such as onclick also run with this set to the element.
7.What is method borrowing in JavaScript?
In short: Calling one object's method on another object through call or apply, which works because a method depends only on what this provides, not on which object it was defined on.
Many built-in methods are written generically: they read this.length and indexed properties, so they work on any array-like value. Array.prototype.map.call on a string maps over its characters, as below, and Array.prototype.slice.call(arguments) was the standard way to turn a function's arguments into a real array before Array.from and rest parameters. Object.prototype.hasOwnProperty.call(obj, key) is still written for objects that may not inherit from Object.prototype, such as those made with Object.create(null), though Object.hasOwn now does the same job directly. Borrowing shows why this is a call-time value: the method never knew which object it belonged to.
const up = Array.prototype.map .call("hey", (c) => c + c); console.log(up.join("-")); // hh-ee-yy
How the diagnostic asks it
One question from the JavaScript bank, exactly as a sitting would show it. The bank has 4 on this & functions and 30 across JavaScript.
What happens when this code runs?
"use strict"; const user = { nick: "Neha", hi() { return this.nick; }, }; const hi = user.hi; console.log(user.hi()); console.log(hi());
- 1It prints Neha, then throws a TypeErrorcorrect
- 2It prints Neha twice
- 3It prints Neha, then undefined
- 4It throws a TypeError before printing anything
user.hi() is called on user, so this is user and it prints Neha. hi() is a plain function call, and in strict mode this is undefined in a plain call, so this.nick throws TypeError: Cannot read properties of undefined. It prints Neha twice assumes the method remembers its object, which only user.hi.bind(user) or an arrow function capturing user would do. Then undefined is what happens without strict mode, where this falls back to the global object, which has no nick property. The first call succeeds, so something is printed before the error.
Measure it
Reading answers tells you what’s true. A diagnostic tells you what you get wrong.
10 JavaScript questions across its topics, easy to hard, about fifteen minutes. You get a readiness figure with the arithmetic shown, the topics you missed named, and a practice set sized for today. Free: 1 diagnostic a month and 15 problems a day. No card.