this Binding Rules
Default Binding
When a function is called as a standalone function (not as an object method, constructor, or with explicit this specification via .call(), .apply(), etc.), this typically points to the global object (window in browsers, global in Node.js). In strict mode (use strict), the global object is not used as the default binding, and this is undefined.
function sayHello() {
console.log(this);
}
sayHello(); // In browsers: Window {...}, in Node.js: Global {...}
// Strict mode
(function sayHello() {
'use strict';
console.log(this);
})(); // Output: undefinedImplicit Binding
When a function is called as a method of an object, this points to the object invoking the method.
const user = {
name: 'Alice',
greet: function () {
console.log(this.name);
}
};
user.greet(); // Output: AliceExplicit Binding
The call(), apply(), or bind() methods can explicitly set the value of this.
function greet() {
console.log(this.name);
}
const user = { name: 'Bob' };
greet.call(user); // Output: Bob
greet.apply(user); // Output: Bob
const boundGreet = greet.bind({ name: 'Charlie' });
boundGreet(); // Output: Charlienew Binding
When a function is invoked with the new keyword, a new object is created, and this is bound to that object. The function returns the new object unless it explicitly returns a non-null primitive value or object.
function User(name) {
this.name = name;
}
const alice = new User('Alice');
console.log(alice.name); // Output: AliceArrow Functions
Arrow functions do not create their own this. Instead, they inherit the this value from their enclosing (lexical) scope.
function outer() {
this.name = 'Alice';
let inner = () => console.log(this.name);
inner(); // Output: Alice
}
outer();Special Cases and Pitfalls
Lost Binding
In implicit binding scenarios, if a method is passed or invoked as a standalone function, its original this binding may be lost, reverting to the default binding.
const user = {
name: 'Alice',
greet: function () {
console.log(this.name);
}
};
const logName = user.greet; // Method assigned to a variable
logName(); // Output: undefined or Window {...}, binding to user object is lost
setTimeout(user.greet, 1000); // In timer callback, output is similar, binding to user object is lostSolutions include using bind() to create a new function with a fixed this binding or using arrow functions (which inherit this from their lexical environment).
Binding Priority
The four binding rules have a priority order: new binding > explicit binding > implicit binding > default binding. When multiple rules apply, the highest-priority rule takes precedence.
function greet() {
console.log(this.name);
}
const user = {
name: 'Bob',
greet: greet
};
const boundUser = {
name: 'Charlie',
greet: greet.bind({ name: 'David' })
};
new greet(); // new binding, Output: undefined (function doesn't return a new object)
user.greet(); // implicit binding, Output: Bob
boundUser.greet(); // explicit binding, Output: David
greet(); // default binding, Output: Window {...} or undefined (strict mode)this in ES6 Arrow Functions
Arrow functions do not have their own this value; they inherit this from their lexical context. This means the this value is determined at the time of definition, unaffected by how the function is called.
const user = {
name: 'Alice',
greet: () => {
console.log(this.name);
}
};
user.greet(); // Output: Window {...} or undefined (strict mode), as arrow function inherits global scope's thisTo use the object’s this in an arrow function, switch to a regular function or use bind().
super Keyword
In class methods, the super keyword accesses properties and methods of the parent class. The this inside super refers to the current class instance.
class Parent {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // Calls Parent's constructor, this inside super points to Child instance
this.age = age;
}
introduce() {
super.sayName(); // Calls Parent's sayName, this inside super points to Child instance
console.log(this.age);
}
}
const child = new Child('Alice', 20);
child.introduce(); // Output: Alice, 20The this keyword in JavaScript is a dynamically bound context object whose value depends on the function’s invocation context and method. Understanding and mastering this binding rules—default, implicit, explicit, and new bindings—enables correct implementation of object methods, callbacks, and constructors.



