一文读懂 es6 中class方法中的this绑定
一直以来有这么个疑问? class 的方法中没有自动的绑定this 为什么手动绑定之后,在绑定之后的方法里调用class中的其他的方法(这个方法为什么就能使用this,不也应该是null或者undefined或者window吗) 还是说这就是class的机制?
于是带着这个疑问去寻找答案
在 JavaScript 中,类的方法中的 this 关键字通常会自动绑定到当前实例对象上。然而,当你将一个类的方法提取出来作为独立的函数调用时,this 的绑定就会丢失,变成 undefined(在严格模式下)或全局对象(在非严格模式下),而不是 null。
手动绑定 this 通常使用 bind、call 或 apply 方法来实现。当你手动绑定 this 之后,你实际上是在创建一个新的函数,并且在这个新函数中,this 被固定为你所指定的对象。因此,在绑定之后的方法里调用类中的其他的方法时,this 仍然指向你所绑定的对象,而不是 null。
这是因为当你使用 bind 方法时,bind 会返回一个新的函数,这个新函数中的 this 值会被永久性地绑定到 bind 方法中传入的第一个参数。当你调用这个新函数时,无论是在哪里调用,this 的值都是你绑定的那个对象。
这是 JavaScript 类和对象机制的一部分,确保了在实例方法中调用其他实例方法时,this 能够正确地引用实例对象。如果你在调用方法时不手动绑定 this,而方法是在类之外的地方被调用,那么 this 就不会自动指向类的实例,而是会丢失绑定,这可能会导致 this 指向全局对象或变为 undefined。
因此,手动绑定 this 是为了确保在方法被提取为独立函数之后,依然可以正确地访问类的实例属性和其他方法。
以下会造成this丢失的问题:
事件处理时的
this丢失问题
当将原型方法作为事件处理器传递时(如onClick={this.handleClick}),方法会被作为普通函数调用,此时this会丢失指向实例的绑定17。这是因为JavaScript的函数调用规则决定了this的指向取决于调用方式,而非定义位置。严格模式的影响
React组件默认在严格模式下运行,未绑定的方法调用时this会变为undefined而非全局对象。这与原型链无关,而是函数调用时的上下文问题。性能优化需求
手动绑定(或使用箭头函数)可以避免每次渲染时重新创建新函数,从而优化shouldComponentUpdate的性能。原型方法若未绑定,每次传递都需要bind(this)或箭头函数包装,会产生新函数引用。箭头函数的替代方案
使用箭头函数定义方法(如handleClick = () => {})本质是直接在实例上创建方法,既避免了绑定操作,又保持了this的正确指向。这是现代React更推荐的写法。总结:原型链上的方法虽然可通过实例访问,但作为回调传递时会丢失
this绑定,因此需要手动绑定或使用箭头函数语法。
下面是一个简单的例子,展示了如何在类之外的地方调用类的方法,并解释为什么需要手动绑定 this。
class MyClass {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
sayGoodbye() {
console.log(`Goodbye, ${this.name}!`);
this.afterGoodbye();
}
afterGoodbye() {
console.log(`After goodbye, ${this.name} is still here.`);
}
}
const myInstance = new MyClass('Alice');
// 正常调用类中的方法
myInstance.greet(); // 输出: Hello, my name is Alice
// 将方法提取到类之外并尝试调用
const extractedGreet = myInstance.greet;
extractedGreet(); // 输出: Hello, my name is undefined
// 手动绑定 this 后再调用
const boundGreet = myInstance.greet.bind(myInstance);
boundGreet(); // 输出: Hello, my name is Alice
// 类中的一个方法在类之外调用另一个方法
myInstance.sayGoodbye(); // 输出: Goodbye, Alice! After goodbye, Alice is still here.
// 将另一个方法提取到类之外并尝试调用
const extractedSayGoodbye = myInstance.sayGoodbye;
extractedSayGoodbye(); // 输出: Goodbye, undefined! TypeError: this.afterGoodbye is not a function
// 手动绑定 this 后再调用
const boundSayGoodbye = myInstance.sayGoodbye.bind(myInstance);
boundSayGoodbye(); // 输出: Goodbye, Alice! After goodbye, Alice is still here.
- MyClass 是一个类,其中包含三个方法:greet、sayGoodbye 和 afterGoodbye。
- myInstance 是 MyClass 的一个实例,初始化时 name 属性被设置为 'Alice'。
- greet 方法正常调用时会输出 Hello, my name is Alice,因为 this 指向 myInstance。
- 当我们将 greet 方法提取到类之外并直接调用时,this 不再指向 myInstance,而是指向全局对象(在非严格模式下)或 undefined(在严格模式下),因此输出 Hello, my name is undefined。
- 使用 bind 方法手动绑定 this 到 myInstance 后,再次调用 greet 方法,this 指向 myInstance,输出 Hello, my name is Alice。
- sayGoodbye 方法在类内部调用 afterGoodbye 方法时,this 正常指向 myInstance,因此输出 Goodbye, Alice! After goodbye, Alice is still here.。
- 当我们将 sayGoodbye 方法提取到类之外并直接调用时,this 不再指向 myInstance,导致 this.name 输出 undefined,并且 this.afterGoodbye 不是一个函数,抛出 TypeError。
- 使用 bind 方法手动绑定 this 到 myInstance 后,再次调用 sayGoodbye 方法,this 指向 myInstance,输出 Goodbye, Alice! After goodbye, Alice is still here.。
通过这个例子,你可以看到手动绑定 this 的重要性,特别是在将方法提取到类之外调用时。

浙公网安备 33010602011771号