【js篇】箭头函数中的 this 指向哪里?

627 阅读2分钟

在 JavaScript 中,箭头函数(Arrow Function) 是 ES6 引入的一种新函数语法,它与普通函数在 this 的绑定机制上有本质区别


✅ 一句话总结

箭头函数没有自己的 this,它的 this 是词法作用域继承而来的,也就是说,它会捕获定义时所在上下文的 this 值,并且这个 this 永远不会改变。


✅ 一、箭头函数的 this 特点

特点说明
没有自己的 this箭头函数不会创建自己的 this 上下文
继承外层作用域的 this它的 this 是从定义时的外层函数或全局作用域继承来的
this 固定不变无论怎么调用,this 都不会改变
不能作为构造函数不可以使用 new 调用(因为没有自己的 this

✅ 二、示例解析

示例 1:普通函数 vs 箭头函数的 this

const obj = {
  name: 'Tom',
  sayNameNormal: function() {
    console.log(this.name);
  },
  sayNameArrow: () => {
    console.log(this.name);
  }
};

obj.sayNameNormal(); // 'Tom'(this 指向 obj)
obj.sayNameArrow();  // undefined(this 指向全局对象 window/global)

📌 解释:

  • sayNameNormal 是普通函数,this 指向调用者 obj
  • sayNameArrow 是箭头函数,其 this 继承自外层作用域(全局作用域),此时 this.nameundefined

示例 2:嵌套函数中的 this

const obj = {
  name: 'Tom',
  getArrow() {
    return () => {
      console.log(this === obj); // true
    };
  }
};

const arrowFn = obj.getArrow();
arrowFn(); // true

📌 解释:

  • getArrow() 是一个普通函数,它的 this 指向 obj
  • 箭头函数内部的 this 继承自 getArrow()this,也就是 obj
  • 所以即使 arrowFn 被单独调用,它的 this 依然指向 obj

✅ 三、Babel 转译帮助理解箭头函数的 this

Babel 在将 ES6 箭头函数转译为 ES5 代码时,会使用一个技巧:用变量保存外层 this

ES6 原始代码:

const obj = {
  getArrow() {
    return () => {
      console.log(this === obj);
    };
  }
}

Babel 转译后的 ES5 代码:

var obj = {
  getArrow: function getArrow() {
    var _this = this;
    return function () {
      console.log(_this === obj);
    };
  }
};

📌 总结:

箭头函数本质上是通过“捕获”外层 this 的方式实现的,这与 Babel 的 _this = this 技术是一致的。


✅ 四、常见面试题:setTimeout 中的 this

const obj = {
  name: 'Tom',
  sayHello: function() {
    setTimeout(function() {
      console.log(this.name); // undefined
    }, 1000);
  },
  sayHelloArrow: function() {
    setTimeout(() => {
      console.log(this.name); // 'Tom'
    }, 1000);
  }
};

obj.sayHello();        // 普通函数,this 指向 window
obj.sayHelloArrow();   // 箭头函数,this 继承外层 sayHello 的 this

📌 结论:

在回调函数中使用箭头函数是解决 this 丢失问题的常见做法。


✅ 五、一句话总结

箭头函数的 this 是在定义时就确定的,继承自外层作用域的 this,并且永远不会改变。它是词法作用域绑定的,不是运行时绑定的。因此,在需要稳定 this 的场景(如回调函数、事件处理)中,箭头函数是非常理想的选择。


💡 进阶建议

  • 在 Vue / React 中,组件方法推荐使用箭头函数自动绑定 this
  • 使用 TypeScript 可以更好地理解函数类型和 this 的指向;
  • 使用 ESLint 规则防止误将箭头函数当作构造函数使用;
  • 在类中使用类字段箭头函数(Class Field Arrow Function)可自动绑定 this