The this keyword is one of the most frequently asked JavaScript interview topics. The value of this depends on how a function is called, not where it is written. Some questions below also mention environment-specific behavior where interviewers commonly ask follow-up questions.
Question 1
const user = {
name: "John",
getName() {
return this.name;
}
};
console.log(user.getName());
The method is called through user, so this refers to user.
Question 2
const obj = {
value: 100,
getValue() {
return this.value;
}
};
const another = {
value: 200,
getValue: obj.getValue
};
console.log(another.getValue());
this depends on the calling object.
Question 3
const user = {
name: "Peter",
getName() {
return this.name;
}
};
const fn = user.getName;
console.log(fn());
Interview assumption: strict mode / ES module behavior.
The function is detached from the object, so this becomes undefined and this.name is undefined.
Non-strict browser environments may behave differently.
Question 4
const obj = {
value: 10,
getValue() {
return this.value;
}
};
console.log((obj.getValue)());
Extra parentheses do not change the calling object.
Question 5
const obj = {
value: 10,
getValue() {
return this.value;
}
};
const fn = obj.getValue;
console.log(fn === obj.getValue);
Both references point to the same function object.
Question 6
const user = {
name: "John",
show: () => {
return this.name;
}
};
console.log(user.show());
Arrow functions do not create their own this.
Interview assumption: common browser/module interview expectation where no global name property exists.
Question 7
const user = {
name: "John",
show() {
const inner = () => this.name;
return inner();
}
};
console.log(user.show());
The arrow function inherits this from show().
Question 8
const user = {
name: "John",
show() {
function inner() {
return this?.name;
}
return inner();
}
};
console.log(user.show());
The regular function gets its own this.
Optional chaining avoids runtime errors.
Question 9
const user = {
age: 25,
getAge() {
return this.age;
}
};
console.log(user["getAge"]());
Bracket notation still calls the method through the object.
Question 10
const user = {
name: "John",
getName() {
return this.name;
}
};
const temp = user;
console.log(temp.getName());
temp references the same object.
Question 11
const obj = {
value: 50,
getValue() {
return this.value;
}
};
const another = obj;
another.value = 100;
console.log(obj.getValue());
Both variables reference the same object.
Question 12
const obj = {
value: 10,
show() {
return () => this.value;
}
};
console.log(obj.show()());
The returned arrow function inherits this from show().
Question 13
const obj = {
value: 10,
show() {
return function() {
return this?.value;
};
}
};
console.log(obj.show()());
The returned regular function loses the object context.
Question 14
const obj = {
value: 20,
show() {
return this.value;
}
};
console.log(typeof obj.show);
Methods are still functions.
Question 15
const obj = {
value: 30,
show() {
return this.value;
}
};
console.log(obj.show === obj.show);
The same function reference is compared.
Question 16
const obj = {
value: 99,
show() {
return this.value;
}
};
console.log(typeof obj.show());
show() returns 99.
Question 17
const obj = {
value: 10,
show() {
return this.value;
}
};
const result = obj.show();
console.log(result);
The method executes with the correct object context.
Question 18
const user = {
name: "John",
show() {
return this;
}
};
console.log(user.show() === user);
The method returns the object itself.
Question 19
const obj = {
value: 100,
show() {
return () => () => this.value;
}
};
console.log(obj.show()()());
Every arrow function inherits the same this value.
Question 20
const obj = {
value: 100,
show() {
return function() {
return function() {
return this?.value;
};
};
}
};
console.log(obj.show()()());
Each regular function receives its own this. The original object context is lost.
Question 21
function greet() {
return this.name;
}
const user = {
name: "John"
};
console.log(greet.call(user));
call() explicitly sets this.
Question 22
function add(a, b) {
return a + b;
}
console.log(add.call(null, 2, 3));
Arguments are passed individually with call().
Question 23
function greet(city) {
return this.name + " " + city;
}
const user = {
name: "John"
};
console.log(
greet.apply(user, ["Delhi"])
);
apply() accepts arguments as an array.
Question 24
function greet() {
return this.name;
}
const user = {
name: "Peter"
};
const fn = greet.bind(user);
console.log(fn());
bind() creates a new function with fixed this.
Question 25
function greet() {
return this.name;
}
const user = {
name: "John"
};
const fn = greet.bind(user);
console.log(typeof fn);
bind() returns a new function.
Question 26
function show() {
return this.value;
}
const obj = {
value: 10
};
console.log(show.call(obj));
call() changes the execution context.
Question 27
function show() {
return this.value;
}
const obj = {
value: 20
};
console.log(
show.apply(obj)
);
apply() also changes the execution context.
Question 28
function show() {
return this.value;
}
const obj = {
value: 30
};
const fn = show.bind(obj);
console.log(fn());
bind() permanently binds this.
Question 29
const person = {
name: "John"
};
const employee = {
name: "Peter"
};
function greet() {
return this.name;
}
console.log(greet.call(employee));
The object passed to call() becomes this.
Question 30
function greet(a, b) {
return a + b;
}
console.log(
greet.apply(null, [5, 7])
);
apply() spreads array values as parameters.
Question 31
function User(name) {
this.name = name;
}
const user = new User("John");
console.log(user.name);
new creates a new object and binds this to it.
Question 32
function User(name) {
this.name = name;
}
const user = new User("Peter");
console.log(
user instanceof User
);
The object is created from User.
Question 33
function User() {
this.age = 25;
}
const user = new User();
console.log(user.age);
Properties are assigned to the created object.
Question 34
function User() {
this.name = "John";
return {
name: "Peter"
};
}
const user = new User();
console.log(user.name);
Returning an object overrides the default object created by new.
Question 35
function User() {
this.name = "John";
return 100;
}
const user = new User();
console.log(user.name);
Primitive return values are ignored by new.
Question 36
function User(name) {
this.name = name;
}
User.prototype.getName = function() {
return this.name;
};
const user = new User("John");
console.log(user.getName());
this refers to the instance calling the method.
Question 37
function User(name) {
this.name = name;
}
const user = new User("John");
console.log(
typeof user
);
Constructor instances are objects.
Question 38
function show() {
return this.value;
}
const obj = {
value: 10
};
const bound = show.bind(obj);
console.log(bound.call({
value: 50
}));
A bound function ignores later call() bindings.
Question 39
function show() {
return this.value;
}
const fn = show.bind({
value: 10
});
const fn2 = fn.bind({
value: 20
});
console.log(fn2());
Once bound, the original this cannot be replaced by another bind().
Question 40
const obj = {
value: 10
};
const arrow = () => this?.value;
console.log(
typeof arrow
);
Arrow functions are still functions. Their this behavior differs, but typeof remains "function".
Question 41
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
const user = new User("John");
console.log(user.getName());
Class methods use the instance as this.
Question 42
class User {
constructor(name) {
this.name = name;
}
}
const user = new User("Peter");
console.log(user.name);
The constructor assigns properties to the instance.
Question 43
class User {
constructor() {
this.value = 10;
}
getValue() {
return this.value;
}
}
const user = new User();
const fn = user.getValue.bind(user);
console.log(fn());
bind() preserves the instance context.
Question 44
class User {
constructor() {
this.value = 20;
}
getValue() {
return this.value;
}
}
const user = new User();
const fn = user.getValue;
try {
console.log(fn());
} catch {
console.log("Error");
}
Class methods run in strict mode. Detached method calls make this undefined.
Question 45
const obj = {
value: 100,
show() {
return this.value;
}
};
const fn = obj.show.bind(obj);
console.log(fn());
bind() permanently fixes this.
Question 46
const obj = {
value: 10,
show() {
setTimeout(() => {
console.log(this.value);
}, 0);
}
};
obj.show();
The arrow callback inherits this from show().
Question 47
const obj = {
value: 10,
show() {
const self = this;
setTimeout(function() {
console.log(self.value);
}, 0);
}
};
obj.show();
The classic self pattern preserves access to the object.
Question 48
const obj = {
value: 50,
show() {
return (() => this.value)();
}
};
console.log(obj.show());
The arrow function captures this from show().
Question 49
const obj = {
value: 75,
show() {
return function() {
return this?.value;
};
}
};
console.log(obj.show()());
The returned regular function loses the original object context.
Question 50
const obj = {
value: 10,
show() {
return (() => (() => this.value)())();
}
};
console.log(obj.show());
Nested arrow functions keep the same this.
Question 51
function User(name) {
this.name = name;
}
User.prototype.getName = function() {
return this.name;
};
const user = new User("John");
console.log(user.getName());
Prototype methods use the calling instance.
Question 52
function User(name) {
this.name = name;
}
const user = new User("Peter");
console.log(
user instanceof User
);
The object was created using User.
Question 53
const obj = {
value: 30
};
function show() {
return this.value;
}
console.log(
show.call(obj)
);
call() explicitly provides this.
Question 54
const obj = {
value: 90
};
function show() {
return this.value;
}
console.log(
show.bind(obj)()
);
The bound function always uses obj as this.
Question 55
const obj = {
value: 1,
show() {
return this.value;
}
};
console.log(
obj.show.call({
value: 999
})
);
call() overrides the normal calling object.
Question 56
const obj = {
value: 5,
show() {
return this;
}
};
console.log(
obj.show() === obj
);
The method returns the object itself.
Question 57
class User {
constructor(name) {
this.name = name;
}
getName = () => this.name;
}
const user = new User("Alex");
console.log(user.getName());
Class field arrow functions capture the instance this.
Question 58
class User {
constructor() {
this.value = 42;
}
getValue = () => this.value;
}
const user = new User();
const fn = user.getValue;
console.log(fn());
Arrow functions keep the lexical this even when detached.
Question 59
const obj = {
value: 10,
show() {
return (() => this)();
}
};
console.log(
obj.show() === obj
);
The arrow function inherits this from show().
Question 60
const obj = {
value: 100,
show() {
return (() => (() => (() => this.value)())())();
}
};
console.log(obj.show());
All nested arrow functions share the same lexical this.