[JS Daily] ES6 箭头函数 vs 普通函数:this 绑定是关键 #JavaScript #ES6 #教程

ES6 箭头函数 vs 普通函数:this 绑定是关键

2026-04-16 | JavaScript Daily #Week1

ES6 引入的箭头函数(Arrow Function)是 JavaScript 中最广泛使用的新语法之一。它写法简洁,但和普通函数之间有一个根本性的差异:this 的绑定方式。理解这一点,是避免踩坑的关键。

一、语法对比:从冗长到简洁

普通函数的写法大家都熟悉:

// 普通函数
const add = function(a, b) {
  return a + b;
};

// 箭头函数
const add = (a, b) => a + b;

箭头函数省略了 function 关键字,当函数体只有一个表达式时,连 return 和花括号都可以省略。

几种常见写法:

// 无参数
const greet = () => "Hello";

// 单参数(可省略括号)
const double = x => x * 2;

// 多行函数体需要花括号和 return
const sum = (a, b) => {
  const result = a + b;
  return result;
};

// 返回对象字面量需加括号
const createUser = (name) => ({ name, role: "user" });

二、核心差异:this 绑定

这是箭头函数和普通函数最本质的区别。

核心规则:

普通函数的 this 取决于调用方式;箭头函数的 this 取决于定义位置(词法作用域)。

看一个经典的坑:

const team = {
  name: "Alpha",
  members: ["Alice", "Bob"],

  // ❌ 普通函数 — this 丢失
  showMembersWrong: function() {
    this.members.forEach(function(member) {
      console.log(member + " is in " + this.name);
      // this.name → undefined!
      // 因为 forEach 回调的 this 指向全局/undefined
    });
  },

  // ✅ 箭头函数 — this 正确继承
  showMembersRight: function() {
    this.members.forEach((member) => {
      console.log(member + " is in " + this.name);
      // this.name → "Alpha" ✅
      // 箭头函数继承外层 this
    });
  }
};

普通函数作为回调时,this 会被重新绑定(在严格模式下是 undefined)。箭头函数没有自己的 this,它从定义时所在的作用域继承。

三、不能用箭头函数的场景

箭头函数虽好,但以下场景必须用普通函数:

1. 对象方法

const obj = {
  count: 10,

  // ❌ 箭头函数 — this 指向外层(window/undefined)
  increment: () => {
    this.count++; // 不work!
  },

  // ✅ 普通函数 — this 指向 obj
  incrementCorrect: function() {
    this.count++;
  }
};

2. 需要使用 arguments 对象

// ❌ 箭头函数没有 arguments
const sum = () => {
  console.log(arguments); // ReferenceError 或指向外层
};

// ✅ 用剩余参数替代
const sum = (...args) => {
  return args.reduce((a, b) => a + b, 0);
};

3. 构造函数

// ❌ 箭头函数不能当构造函数
const Person = (name) => {
  this.name = name;
};
new Person("Alice"); // TypeError: Person is not a constructor

// ✅ 用普通函数或 class
class Person {
  constructor(name) {
    this.name = name;
  }
}

4. 事件监听器中需要 this 指向 DOM 元素

const btn = document.querySelector("#myBtn");

// ❌ this 不会指向按钮
btn.addEventListener("click", () => {
  console.log(this); // 外层 this,不是按钮
});

// ✅ 普通函数 this 指向按钮
btn.addEventListener("click", function() {
  console.log(this); // <button> 元素
});

四、完整对比表

特性 普通函数 箭头函数
this 绑定 动态,取决于调用 词法,继承外层
arguments ✅ 有 ❌ 没有
构造函数 (new) ✅ 可以 ❌ 不可以
prototype ✅ 有 ❌ 没有
call/apply/bind ✅ 可以改变 this ❌ 无效
yield (生成器) ✅ 可以 ❌ 不可以

五、最佳实践总结

// ✅ 箭头函数适合的场景

// 1. 回调函数(数组方法等)
const doubled = [1, 2, 3].map(n => n * 2);

// 2. Promise 链
fetch(url)
  .then(res => res.json())
  .then(data => process(data));

// 3. 需要保留外层 this 的场景
class Timer {
  constructor() {
    this.seconds = 0;
    setInterval(() => {
      this.seconds++; // ✅ this 正确指向 Timer
    }, 1000);
  }
}

记住一句话:需要自己的 this → 用普通函数;不需要自己的 this → 用箭头函数。

箭头函数不只是语法糖,它的 this 词法绑定特性解决了 JavaScript 长期以来最令人困惑的问题之一。选对场景用对函数,代码会更简洁也更可靠。

#JavaScript #ES6 #箭头函数 #教程 | JavaScript Daily 系列

评论

此博客中的热门博文

OpenClaw 救援机器人建设与演进全记录 - 从单点故障到双实例自愈体系

Lossless Claw:无损上下文管理插件分析报告

[Hello-Agents] Day 2: 第一章 初识智能体