箭头函数表达式的语法比传统的函数表达式更简洁,但在语义上有一些差异,在用法上也有一些限制
1. this的绑定方式
普通函数
- 会根据外部调用来决定
this的绑定指向(谁调用,this就指向谁) - 可以通过
call/apply/bind手动改变this的指向
function testFunc() {
console.log(this);
}
const obj = { method: testFunc };
obj.method(); // 此时this 指向 obj
箭头函数
- 集成外层函数/全局的this(定义时候就已经决定好,不可进行改变)
- 无法通过
call/apply/bind手动改变this的指向
const testFunc = () => console.log(this);
const obj = { method: testFunc };
obj.method(); // 此时this 指向外层作用域 - window
2. 构造函数能力
普通函数
- 可以通过
new创建实例 - 拥有
prototype属性
const Foo = function() {};
const foo = new Foo(); // 正常工作
箭头函数
- 不能作为构造函数使用,即无法通过
new来创建实例 - 没有
prototype属性
const Bar = () => {};
const bar = new Bar(); // 抛出错误:Bar is not a constructor
3. arguments
普通函数
普通函数可以访问arguments对象(包含传递给函数的所有参数)
function testFunc() {
console.log(arguments); // 打印类数组对象[Arguments] { '0': 1, '1': 2, '2': 3 }
}
// 传入参数
testFunc(1, 2, 3);
// 调用外层函数,并传入参数 testFunc(1, 2, 3);
箭头函数
箭头函数没有自己的 arguments 对象,会从外层作用域继承 arguments,或是使用展开运算符...args获取参数
function outerFunction() {
const innerFunction = () => {
// 箭头函数没有自己的arguments对象,此时使用外层函数的 arguments 对象
console.log(arguments);
};
// 调用箭头函数
innerFunction();
}
outerFunction(1, 2, 3);
// ......
const testFunc = (...args) => {
console.log(args); // 输出:[1, 2, 3]
};
testFunc(1, 2, 3);
写法差异
普通函数
可以包含 return、yield 和 await 等语句。
箭头函数
- 箭头函数的简化形式(省略大括号
{})隐式返回值,不能包含return、yield或await。 - 如果需要使用这些语句,必须使用完整的大括号形式。
const foo = () => {
return "Hello"; // 显式返回值
};
const bar = () => "Hello"; // 隐式返回值
| 特性 | 普通函数 | 箭头函数 |
|---|---|---|
| 写法 | function() {} | () => {} |
| 隐式返回 | 需显式 return | 单行表达式可省略 {} 和 return |
| 命名 | 支持函数名 | 通常匿名(可通过变量赋值) |
总结
| 特性 | 普通函数 | 箭头函数 |
|---|---|---|
this | 有自己的 this,取决于调用方式 | 没有自己的 this,继承外层作用域 |
arguments | 可以访问 arguments 对象 | 没有自己的 arguments,继承外层作用域 |
prototype | 有 prototype 属性 | 没有 prototype 属性 |
| 语法简洁性 | 冗长 | 更简洁,适合简短的回调 |
| 构造函数 | 可以用作构造函数 | 不能用作构造函数 |
| 使用场景 | 需要独立的 this 或 prototype | 简短的回调,避免 this 绑定问题 |