在 JavaScript 中,箭头函数和普通函数(通过 function 声明的函数)有以下几个核心区别,主要围绕 this 绑定、用法限制和语言特性展开:
| 特性 |
普通函数 |
箭头函数 |
this 确定方式 |
运行时动态绑定(谁调用,this 就指向谁) |
静态继承(继承父级作用域的 this,不可修改) |
| 是否可被修改 |
可通过 call/apply/bind 修改 this |
无法修改,始终继承定义时的上下文 |
const obj = {
name: 'Alice',
sayNormal: function() {
console.log(this.name); // 正常指向 obj(调用者)
},
sayArrow: () => {
console.log(this.name); // this 指向全局(如 window/undefined)
}
};
obj.sayNormal(); // 输出 'Alice'
obj.sayArrow(); // 输出 undefined(严格模式)或全局对象的 name
| 特性 |
普通函数 |
箭头函数 |
| 能否作为构造函数 |
✅ 可以(通过 new 实例化对象) |
❌ 不可(无 [[Construct]] 内部方法) |
prototype 属性 |
✅ 拥有 |
❌ 无 |
function Car() {} // 普通函数可用作构造函数
const CarArrow = () => {};
new Car(); // 正常创建实例
new CarArrow(); // 抛出 TypeError: CarArrow is not a constructor
| 特性 |
普通函数 |
箭头函数 |
是否关联 arguments |
✅ (类数组参数对象) |
❌ 无(但可通过剩余参数 ...args 替代) |
function normalFn(a, b) {
console.log(arguments); // 类数组:Arguments(2) [1, 2]
}
const arrowFn = (a, b) => {
console.log(arguments); // 报错:arguments is not defined
};
normalFn(1, 2);
arrowFn(1, 2);
| 特性 |
普通函数 |
箭头函数 |
| 语法简洁性 |
要求完整语法(适合复杂逻辑或多行代码) |
支持简写(单行返回值可省略 {}和 return) |
| 适用场景 |
对象方法、构造函数、动态this的场景(如事件回调) |
回调函数、需要继承上下文的场景(如 setTimeout) |
const add = (a, b) => a + b; // 单行返回,无需 {} 和 return
| 特性 |
普通函数 |
箭头函数 |
生成器函数 function* |
✅ 支持声明生成器 |
❌ 不可用 |
super 和 new.target |
支持 |
不支持(继承父级作用域的行为) |
| 匿名性 |
可为命名函数或匿名函数 |
始终匿名,但可通过变量赋值引用 |
-
箭头函数适用场景:
- 需要固定
this 的上下文(如事件监听器的回调)。
- 简写函数表达式(如数组方法
map/filter)。
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
-
普通函数适用场景:
- 对象的方法定义(需要动态
this)。
- 构造函数或需要
prototype 的场景。
- 需要使用
arguments 或生成器函数时。
核心原则:根据 this 的需求决定用哪种函数类型,避免在需要动态上下文中误用箭头函数。