JavaScript 普通函数与箭头函数的核心差异及 this 绑定机制
本文深入解析 JavaScript 中普通函数与箭头函数的区别。重点阐述箭头函数不绑定自身 this,而是沿作用域链查找;同时指出箭头函数缺少 arguments、super 等局部变量。通过代码示例对比两者的 this 固定方式及参数处理方式,并探讨在函数式编程与普通场景下的适用性。
普通函数与箭头函数的核心差异
近期遇到一个常见面试题:
JavaScript 中的箭头函数 ( => ) 与普通函数 ( function ) 存在哪些具体差异?
起初我认为该问题十分基础,但随后给出的回答却存在偏差……
许多人认为箭头函数中的 this 与调用时的上下文无关,而是取决于定义时的上下文。
这一观点并不完全准确,虽然并非全然错误。
关于箭头函数中的 this 行为
首先确认之前回答中正确的部分:箭头函数中的 this 确实不与调用时的上下文绑定。
箭头函数中的 this 绑定机制
function make () {
return ()=>{
console.log(this);
}
}
const testFunc = make.call({ name:'foo' });
testFunc(); //=> { name:'foo' }
testFunc.call({ name:'bar' }); //=> { name:'foo' }
通过示例可见,箭头函数在定义后,其 this 指向便固定不变,无论采用何种方式调用,this 均保持恒定;
然而严格来说,这并非“取决于定义时的上下文”,因为箭头函数本身并未绑定自己的 this。在箭头函数内部调用 this 时,实际上是沿着作用域链向上查找,使用最近外层作用域中的 this。从效果看,这似乎与之前的理解相似,但本质截然不同:箭头函数并非普通函数新增了 this 不受调用上下文影响的特性,而是省略了部分特性。
箭头函数本质上是更简化的函数形式
实际上,箭头函数中不仅 this 与普通函数不同,它还缺乏其他自动绑定的局部变量,包括:this、arguments、super (ES6)、new.target (ES6) 等。
参考以下示例:
局部变量与 arguments 的处理
function foo() {
setTimeout( () => {
console.log("args:", arguments);
},100);
}
foo( 2, 4, 6, 8 );
// args: [2, 4, 6, 8]
在普通函数中自动绑定的各类局部变量,在箭头函数中均表现为沿作用域链向上查找。
箭头函数正是这样一种简洁且纯粹的存在。
因此,个人倾向于认为箭头函数更契合函数式编程风格。除了语法更简短外,使用箭头函数能降低因未显式声明变量影响计算结果的风险,从而避免意外的计算结果。
那么,普通函数能否实现与箭头函数相同的效果呢?
若仅考虑固定 this 这一易变变量,实现起来相对简单,常见方法如下:
普通函数模拟箭头函数效果
function make () {
var self = this;
return function () {
console.log(self);
}
}
或者采用另一种方式:
function make () {
return function () {
console.log(this);
}.bind(this);
}
然而第二种方法仅能固定 this 这一个变量。如前文所述,箭头函数中的 arguments 等变量同样从作用域链中获取。为实现类似效果,我们只能重新定义局部变量,Babel 对箭头函数的转换也正是采用此方式。
function make () {
return ()=>{
console.log(this);
console.log(arguments);
}
}
//babel it...
function make() {
var _this = this,
_arguments = arguments;
return function () {
console.log(_this);
console.log(_arguments);
};
}
那么,若需在箭头函数中使用 arguments 该怎么办?
……若有此需求,使用普通函数可能更为合适。
但这并不意味着在箭头函数中无法以数组形式获取所有参数,我们可以利用展开运算符来接收参数,例如:
箭头函数中参数的接收方式
const testFunc = (...args)=>{
console.log(args) //数组形式输出参数
}
或许确实存在需要此类写法的场景,但我仍认为,箭头函数更适合那些接受固定参数并返回计算结果的简单情况。
以上内容为 JavaScript 普通函数与箭头函数的区别及用法详解,希望对大家有所帮助。如有疑问请留言,小编会及时回复。感谢支持!
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
