箭头函数和普通函数有什么区别?this 指向怎么解释?
面试速答(30 秒版 TL;DR)
- 箭头函数的
this是词法绑定:它不创建自己的this,而是捕获定义时外层作用域的this。 - 箭头函数没有
arguments、不能用new(不是构造器)、也没有自己的prototype。 - 适合做回调(尤其需要稳定
this时),不适合做对象方法(需要动态this的场景)。
this:动态绑定 vs 词法绑定
普通函数的 this 取决于“怎么调用”:
const obj = {
x: 1,
f() {
return this.x;
},
};
obj.f(); // 1
const g = obj.f;
g(); // 非严格模式可能是 undefined/全局,严格模式是 undefined
箭头函数的 this 取决于“定义在哪”:
const obj = {
x: 1,
f() {
const inner = () => this.x;
return inner();
},
};
obj.f(); // 1
不能当构造函数(高频)
const A = () => {};
new A(); // TypeError: A is not a constructor
原因:箭头函数没有 [[Construct]],也没有 prototype 用来挂实例方法。
没有 arguments
function f() {
const g = () => arguments[0];
return g(2);
}
f(1); // 1(捕获外层 arguments)
如果需要可变参数,优先用 rest:
const sum = (...xs) => xs.reduce((a, b) => a + b, 0);
典型题 & 标准答法
Q1:为什么箭头函数能“解决 this 丢失”?
答法要点:
- 回调里
this常因调用方式变化而变化。 - 箭头函数没有自己的
this,直接用外层的this,因此稳定。
Q2:对象方法能用箭头函数吗?
不推荐作为方法:
const obj = {
x: 1,
f: () => this.x,
};
obj.f(); // 通常不是 1(this 不是 obj)
结论:方法用普通函数,回调用箭头函数更常见。
易错点/坑
- 误以为箭头函数的
this是“调用者”:不是,它是“定义时外层 this”。 - 把箭头函数当构造器用。
速记要点(可背诵)
- 箭头函数:词法 this、无 arguments、不能 new、无 prototype。
- 适合回调,不适合作为需要动态 this 的对象方法。