Four binding methods for this
In JavaScript, the binding of this primarily follows four rules, listed below in order of priority from highest to lowest:
1. New Binding
When a function is invoked with the new keyword (i.e., as a constructor), a new object is created, and this is bound to that new object.
function Person(name) {
this.name = name;
}
const p = new Person('Damo');
console.log(p.name); // 'Damo'
Here,
thisrefers to the newly created instance.
2. Explicit Binding
You can explicitly set the value of this using the methods call, apply, or bind.
function greet() {
console.log(`Hello, ${this.name}`);
}
const obj = { name: 'Damo' };
greet.call(obj); // Hello, Damo
greet.apply(obj); // Hello, Damo
const boundGreet = greet.bind(obj);
boundGreet(); // Hello, Damo
Note:
bindreturns a new function whosethisis permanently bound (unless the function is invoked withnew).
3.Implicit Binding
When a function is called as a method of an object, this is bound to that object.
const obj = {
name: 'Damo',
sayHi() {
console.log(this.name);
}
};
obj.sayHi(); // Damo
⚠️ Beware of “implicit loss”: if you assign the method to a variable or pass it as a callback, the
thiscontext may be lost.
const fn = obj.sayHi;
fn(); // undefined (or global object in non-strict mode)
4. Default Binding
When a function is called independently (with no context), this uses the default binding:
- In non-strict mode,
thisrefers to the global object (windowin browsers,globalin Node.js). - In strict mode (
'use strict'),thisisundefined.
function foo() {
console.log(this);
}
foo(); // 非严格模式:window;严格模式:undefined
Additional Note: Arrow Functions
Arrow functions do not have their own this. Instead, they lexically inherit this from the enclosing scope, so they are not affected by the four binding rules above.
const obj = {
name: 'Damo',
greet: () => {
console.log(this.name); // this 指向外层(通常是 window 或 undefined)
},
greetNormal() {
const arrow = () => console.log(this.name);
arrow(); // 'Damo',因为箭头函数继承了 greetNormal 的 this
}
};
obj.greet(); // undefined
obj.greetNormal(); // Damo
Priority Summary (Highest to Lowest):
- New Binding
- Explicit Binding (
call/apply/bind) - Implicit Binding (method calls on objects)
- Default Binding (standalone function calls)
Arrow functions bypass these rules entirely—they capture
thislexically at definition time.
Thought Experiment (a.k.a. “Looking for Trouble” Section):
- What happens if you call the
call,apply, orbindmethods on a function that is invoked withnew? - What happens when you use
newon a method of an object versus usingnewon a method of a class? - Can you directly assign a value to
this? For example:
this = { a: 'Hello' };