箭头函数与普通函数的区别
对比箭头函数和普通函数在 this、arguments、new 等方面的差异
问题
箭头函数与普通函数有哪些区别?主要从 this 绑定、arguments 对象、new 调用等方面说明。
解答
1. this 绑定
箭头函数没有自己的 this,它会捕获定义时所在上下文的 this。
const obj = {
name: 'obj',
// 普通函数:this 指向调用者
regular() {
console.log(this.name); // 'obj'
},
// 箭头函数:this 继承外层作用域
arrow: () => {
console.log(this.name); // undefined(this 指向全局/外层)
}
};
obj.regular(); // 'obj'
obj.arrow(); // undefined
常见场景:回调函数中保持 this 指向
function Timer() {
this.seconds = 0;
// 普通函数:this 丢失
setInterval(function() {
this.seconds++; // this 指向 window,不是 Timer 实例
}, 1000);
// 箭头函数:this 保持指向 Timer 实例
setInterval(() => {
this.seconds++; // 正确,this 指向 Timer 实例
}, 1000);
}
2. arguments 对象
箭头函数没有自己的 arguments,访问的是外层函数的 arguments。
function regular() {
console.log(arguments); // Arguments [1, 2, 3]
}
const arrow = () => {
console.log(arguments); // ReferenceError: arguments is not defined
};
regular(1, 2, 3);
arrow(1, 2, 3);
箭头函数中获取参数,使用 rest 参数:
const arrow = (...args) => {
console.log(args); // [1, 2, 3]
};
arrow(1, 2, 3);
3. 不能作为构造函数
箭头函数没有 [[Construct]] 内部方法,不能使用 new 调用。
function Regular() {
this.value = 1;
}
const Arrow = () => {
this.value = 1;
};
new Regular(); // OK
new Arrow(); // TypeError: Arrow is not a constructor
4. 没有 prototype 属性
function regular() {}
const arrow = () => {};
console.log(regular.prototype); // {constructor: f}
console.log(arrow.prototype); // undefined
5. 不能用作 Generator
箭头函数不能使用 yield 关键字。
// 普通函数可以
function* generator() {
yield 1;
}
// 箭头函数不行,语法错误
const arrowGen = *() => {
yield 1;
}; // SyntaxError
6. call/apply/bind 无法改变 this
const obj1 = { name: 'obj1' };
const obj2 = { name: 'obj2' };
const arrow = () => {
console.log(this.name);
};
arrow.call(obj1); // undefined(this 不变)
arrow.apply(obj2); // undefined(this 不变)
arrow.bind(obj1)(); // undefined(this 不变)
关键点
- this:箭头函数没有自己的 this,继承定义时外层作用域的 this,且无法通过 call/apply/bind 修改
- arguments:箭头函数没有 arguments 对象,需用 rest 参数
...args替代 - 构造函数:箭头函数不能用 new 调用,没有 prototype 属性
- Generator:箭头函数不能使用 yield,不能作为生成器函数
- 适用场景:箭头函数适合回调、需要保持 this 的场景;普通函数适合对象方法、构造函数、需要 arguments 的场景
目录