人人都会AI编程

5.4 箭头函数的 this 特性:词法 this、无自身 this

更新时间:2026-07-11

箭头函数是 ES6 引入的简洁函数语法,它除了写法更短,还有一项颠覆性的行为差异:没有自己的 this。它的 this 值在函数定义时就已确定,永远指向外层作用域的 this,这个特性被称为词法 this

普通函数 vs 箭头函数的 this

通过一个经典对比来理解:

const obj = {
  name: '张三',
  // 普通函数
  normalFunc: function() {
    console.log(this.name); // this 取决于调用方式
  },
  // 箭头函数
  arrowFunc: () => {
    console.log(this.name); // this 来自定义时的外层作用域
  }
};

obj.normalFunc(); // '张三' —— this 指向 obj
obj.arrowFunc();  // undefined —— this 指向全局对象(浏览器中是 window)

普通函数 normalFunc 作为对象方法调用,this 隐式绑定到 obj,所以输出“张三”。
箭头函数 arrowFunc 定义在对象字面量内,但它的外层作用域是全局作用域,因此 this 指向全局对象(严格模式下为 undefined),输出 undefined

为什么箭头函数没有自己的 this

箭头函数的设计初衷之一就是解决回调函数中 this 丢失的问题。在 React 或定时器、事件监听中,我们经常需要在外层函数中引用 this,但普通函数会将 this 重新绑定到调用者,导致外层 this 丢失。

class Counter {
  constructor() {
    this.count = 0;
    // 传统解决方案:用变量保存 this
    const self = this;
    setInterval(function() {
      console.log(self.count++); // 必须用 self
    }, 1000);
  }
}

使用箭头函数后,代码变得干净且不易出错:

class Counter {
  constructor() {
    this.count = 0;
    setInterval(() => {
      console.log(this.count++); // this 自动绑定到 Counter 实例
    }, 1000);
  }
}

因为箭头函数没有自己的 this,它直接使用定义时所在作用域的 this(此处为 constructor 中的 this),即 Counter 实例。

不能修改 this 指向

箭头函数的 this 是词法固定的,因此 callapplybind 对它无效。调用这些方法只会传递参数,不会改变 this

const arrow = () => console.log(this);
const bound = arrow.bind({ name: 'test' });
bound(); // this 仍然是外层作用域的值,不会变成 { name: 'test' }

箭头函数的使用限制

正因为没有自己的 this,箭头函数不能用作构造函数new 会报错),也不具备 prototype 属性。此外,它也没有 arguments 对象(但可以使用剩余参数 ...args 代替)。

什么时候该用箭头函数

  • 需要保留外层 this 的回调:定时器、Promise 链、事件监听器(如果希望 this 固定为组件实例)
  • 简洁的纯函数:数组方法(mapfilterreduce)中的处理函数
  • 避免绑定浪费:不需要再写 bind(this)const self = this

什么时候不该用

  • 对象方法:如果方法内依赖 this 指向该对象,请使用普通函数或 ES6 方法简写
  • 需要动态 this 的场景:如构造函数、原型方法
  • 需要操作 arguments 对象的地方:用普通函数或剩余参数代替

一句话总结

箭头函数没有自己的 this,它的 this 来自定义时的词法作用域,且无法被改变。这一特性让它成为回调函数中保留外层 this 的完美工具,但同时也限制了它在需要动态 this 场景下的使用。