总结
特性 | 箭头函数 | 普通函数 |
---|---|---|
this 绑定 | 继承定义位置的上下文 (词法作用域 ) | 由调用方式决定(调用者) |
构造函数调用 | 不支持,不能使用 new | 支持,可以使用 new |
arguments 对象 | 没有 arguments ,需使用 rest 参数获取 | 有自己的 arguments 对象 |
隐式返回 | 支持单行隐式返回 | 不支持,必须使用 return |
作为对象方法使用 | 不推荐,因为 this 绑定到外部作用域 | 推荐,this 绑定到调用对象 |
性能 | 略微节省内存,因无 this 绑定和 arguments | 性能稳定,尤其在需要绑定上下文时 |
bind /call /apply | 不生效,this 永远指向定义时的上下文 | 支持,可动态绑定 this |
1. 作用域中的 this
绑定
- 箭头函数:箭头函数不会创建自己的
this
,而是从定义位置的上下文中继承this
值。这意味着箭头函数中的this
指向的是它外层最近的非箭头函数的this
,即词法作用域。 - 普通函数:普通函数在调用时会动态地决定
this
的指向。它的this
指向由调用者决定,例如通过直接调用(指向全局对象)、对象方法调用(指向该对象)、构造函数调用(指向新实例)等。
示例:
const obj = {
value: 10,
arrowFunc: () => console.log(this.value), // undefined in non-strict mode
regularFunc() {
console.log(this.value); // 10
}
};
obj.arrowFunc(); // undefined
obj.regularFunc(); // 10
在箭头函数中,this.value
未被定义,因为箭头函数继承的是外部环境的 this
,而非 obj
本身。
2. 使用 new
调用
- 箭头函数:不能作为构造函数使用。如果使用
new
调用箭头函数会抛出错误。 - 普通函数:可以作为构造函数使用,实例化新对象时
this
指向该新实例。
示例:
const ArrowFunc = () => {};
function RegularFunc() {}
new RegularFunc(); // 正常执行
new ArrowFunc(); // 报错:ArrowFunc is not a constructor
3. arguments
对象的处理
- 箭头函数:箭头函数没有
arguments
对象。需要使用 rest 参数 (...args
) 来获取参数数组。 - 普通函数:普通函数内有自己的
arguments
对象,可以通过它访问传入的所有参数。
示例:
function regularFunc() {
console.log(arguments); // [1, 2, 3]
}
const arrowFunc = (...args) => {
console.log(args); // [1, 2, 3]
};
regularFunc(1, 2, 3);
arrowFunc(1, 2, 3);
4. 隐式返回
- 箭头函数:箭头函数可以简化写法,对于单行表达式可以省略
{}
和return
关键字,直接返回结果。 - 普通函数:普通函数必须显式地使用
return
关键字返回结果。
示例:
const add = (a, b) => a + b; // 隐式返回
function addRegular(a, b) {
return a + b; // 必须使用 return
}
5. 作为对象方法使用
- 箭头函数:箭头函数不适合直接作为对象方法,因为它没有自己的
this
,this
会指向定义位置的外部上下文,而不是调用它的对象。 - 普通函数:普通函数更适合作为对象方法,因为它的
this
会指向调用者,即该对象。
示例:
const obj = {
value: 42,
arrowFunc: () => console.log(this.value), // `this` 绑定到外部作用域
regularFunc() {
console.log(this.value); // `this` 绑定到 obj
}
};
obj.arrowFunc(); // undefined
obj.regularFunc(); // 42
6. 性能
- 箭头函数:箭头函数在特定情况下会略微节省内存,尤其是当它们被用于较少的嵌套环境时,因为不需要
this
和arguments
的管理。但是差异在绝大多数情况下是微乎其微的。 - 普通函数:普通函数在某些优化场景下性能可能更好,尤其是函数调用频繁、需要频繁重新绑定
this
的情况。
7. 绑定上下文
- 箭头函数:无法通过
bind()
、call()
或apply()
改变this
的指向。箭头函数的this
永远指向定义时的上下文。 - 普通函数:可以使用
bind()
、call()
、apply()
显式改变this
指向,动态绑定不同的上下文。
箭头函数适用于简短、无 this
需求的函数,而普通函数更适合需要灵活 this
指向和复杂逻辑的场景。