如何在对象方法及箭头函数方法中绑定this?为何bind对箭头函数不生效?
JavaScript中
this绑定的常见问题解答 Hey,这两个问题都是JavaScript里this绑定的经典坑,我来给你掰扯清楚:
1. 如何在对象的方法中绑定this?
根据不同的使用场景,有几种常用的绑定方式:
普通函数方法的默认绑定:
如果你用普通函数定义对象方法,调用时this默认会指向调用这个方法的对象,这是最基础的情况:const person = { name: "anna", hello: function() { console.log(`hello ${this.name}!`); } }; person.hello(); // 输出 "hello anna!",此时this指向person对象固定
this避免回调丢失:
要是这个方法需要作为回调函数(比如setTimeout、事件监听)使用,直接传方法的话this可能会丢失,这时候可以用这些方式绑定:- 提前用
bind()绑定到目标对象:function sayHello() { console.log(`hello ${this.name}!`); } const person = { name: "anna", hello: sayHello.bind(person) }; setTimeout(person.hello, 1000); // 1秒后依然输出"hello anna!" - 在构造函数中绑定(适合批量创建对象的场景):
function Person(name) { this.name = name; this.hello = function() { console.log(`hello ${this.name}!`); }; // 把this绑定到当前实例,避免后续调用丢失 this.hello = this.hello.bind(this); } const anna = new Person("anna"); anna.hello(); // 输出"hello anna!" - ES6类中用箭头函数作为实例属性:
类的实例属性箭头函数会自动绑定到实例的this,不用手动处理:class Person { constructor(name) { this.name = name; } hello = () => { console.log(`hello ${this.name}!`); }; } const anna = new Person("anna"); setTimeout(anna.hello, 1000); // 正常输出
- 提前用
2. 箭头函数类型的方法中绑定this?为何person.hello.bind(person)不生效?
首先得搞懂箭头函数的核心特性:箭头函数没有自己的this,它的this是在定义的时候就确定的,直接继承自外层作用域的this,而且这个this一旦确定,就再也没法通过bind()、call()、apply()来修改——这些方法对箭头函数的this完全无效。
看你给出的代码:
const person = { name: "anna", hello: () => console.log(`hello ${this.name}!`) }; person.hello(); // 输出 "hello undefined!" person.hello.bind(person)(); // 还是输出 "hello undefined!"
为什么会这样?因为这个箭头函数hello是定义在对象字面量里的,它的外层作用域是全局作用域(浏览器里是window,Node.js里是global或者严格模式下的undefined),所以它的this指向的是全局,而全局作用域里没有name属性,自然输出undefined。
至于bind(person)没用,就是因为箭头函数不接受外部传入的this,它的this从出生就固定死了,任何修改操作都会被忽略。
怎么解决这个问题?
如果想让hello方法的this指向person,有两种简单的修改方式:
- 把箭头函数改成普通函数:这是最直接的方案,回到默认的方法绑定规则:
const person = { name: "anna", hello: function() { console.log(`hello ${this.name}!`); } }; person.hello(); // 输出 "hello anna!" - 如果非要用箭头函数,改用class实现:
class的构造函数作用域里的this是实例,箭头函数作为实例属性时,会继承这个this:class Person { constructor(name) { this.name = name; } hello = () => { console.log(`hello ${this.name}!`); }; } const person = new Person("anna"); person.hello(); // 输出 "hello anna!"
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

