ES6 箭头函数(Arrow Functions)与传统的普通函数(使用 function
关键字定义)在语法、行为和使用场景上存在显著差异。以下是它们之间的主要区别:
1. 语法差异 (Syntax)
- 普通函数:
- 使用
function
关键字声明。语法相对冗长。
- 使用
- 箭头函数:
- 使用
=>
(箭头) 语法。 - 语法更简洁,尤其对于单行表达式和单参数函数。
- 使用
2. this
绑定 (The this
Binding) – 最核心的区别
- 普通函数:
- 动态
this
:this
的值是在函数被调用时动态确定的。取决于调用方式:作为对象方法调用时指向对象,直接调用时指向全局对象(或undefined
在严格模式下),通过new
调用时指向新创建的实例,通过call
/apply
/bind
调用时指向指定的对象。
- 动态
- 箭头函数:
- 词法
this
:箭头函数不绑定自己的this
。 - 它的
this
值是在函数被创建时就确定的,继承自外层(包裹它的)普通函数或全局作用域的this
值。 - 无法通过
call
、apply
或bind
改变其this
指向。
- 词法
3. arguments
对象 (The arguments
Object)
- 普通函数:
- 拥有内置的
arguments
对象,它是一个类数组对象,包含所有传入的实参。
- 拥有内置的
- 箭头函数:
- 没有自己的
arguments
对象。 - 如果在箭头函数中访问
arguments
,它会引用外层普通函数的arguments
,如果没有外层普通函数,则会报错。
- 没有自己的
4. 作为构造函数 (Constructor)
- 普通函数:
- 可以用作构造函数,通过
new
操作符调用,创建新的对象实例。
- 可以用作构造函数,通过
- 箭头函数:
- 不能用作构造函数。
- 尝试使用
new
调用会抛出TypeError
错误。 - 因为它没有
[[Construct]]
内部方法,没有prototype
属性。
5. prototype
属性
- 普通函数:
- 拥有
prototype
属性,该属性是一个对象,用于存放可以被实例继承的属性和方法。
- 拥有
- 箭头函数:
- 没有
prototype
属性。
- 没有
6. 使用场景总结
场景 | 推荐使用 |
---|---|
需要动态 this (如对象方法、事件处理器需要指向目标元素) | ✅ 普通函数 |
作为回调函数,且需要保持外层 this (如 setTimeout 、数组方法 map/filter 的回调) | ✅ 箭头函数 |
需要使用 arguments 对象 | ✅ 普通函数 (或箭头函数中用 ...args ) |
需要作为构造函数创建实例 | ✅ 普通函数 或 class |
需要简洁的单行函数 (如 arr.map(x => x * 2) ) | ✅ 箭头函数 |
需要 new 调用或 prototype | ✅ 普通函数 |
总结
特性 | 普通函数 (function ) | 箭头函数 (=> ) |
---|---|---|
this 绑定 | 动态绑定 (调用时确定) | 词法绑定 (创建时继承外层) |
arguments | 有 | 无 (需用 ...args ) |
new 调用 | 可以 | 不可以 |
prototype | 有 | 无 |
语法 | 冗长 | 简洁 |
主要用途 | 构造函数、需要动态 this 的方法 | 回调函数、保持 this 上下文 |
核心要点:箭头函数最大的优势是解决了 this
指向问题,特别适合用作回调。但它牺牲了作为构造函数的能力和 arguments
对象,使用时需根据场景选择。
THE END