普通函数与箭头函数的差异?函数提升仅适用于传统函数吗?
关于函数提升与箭头函数的核心差异
嘿,这个问题我之前也踩过坑!咱们一步步来拆解清楚~
先回答你的核心疑问:函数提升仅适用于传统函数声明吗?
没错!只有函数声明(function foo() {})会被完整提升到当前作用域的顶部,而箭头函数本质是通过const/let声明的变量(变量值是一个函数),它遵循的是变量提升规则,而非函数提升。
这里要注意一个关键概念:const/let声明的变量确实会被提升,但提升后会进入暂时性死区(TDZ)——在变量正式声明语句之前访问它,会直接抛出ReferenceError。这就是你第一个示例报错的原因:
// 此时makeHero处于暂时性死区,访问会报错 form.addEventListener('submit', makeHero, false); const makeHero = (event) => { /* ... */ }
而如果换成传统函数声明:
// 函数声明被完整提升,这里可以正常调用 form.addEventListener('submit', makeHero, false); function makeHero(event) { /* ... */ }
即使把函数声明放在调用之后,JS引擎也会先把整个函数提升到作用域顶部,所以能正常执行。
除了语法和提升规则,普通函数与箭头函数还有这些关键差异
- 没有独立的
this绑定:箭头函数的this继承自外层作用域的this,且一旦确定就无法通过call/apply/bind修改。而普通函数的this会根据调用方式动态变化(比如作为对象方法调用时指向对象,作为普通函数调用时指向全局/undefined)。 - 不能作为构造函数:箭头函数没有
prototype属性,也不能用new关键字调用,否则会抛出TypeError。 - 没有
arguments对象:如果需要获取传入的所有参数,箭头函数里要用剩余参数语法(...args)代替,而普通函数可以直接访问arguments。 - 不能用作生成器函数:箭头函数无法配合
yield关键字使用,不能定义生成器。 - 语法更简洁:对于单语句的函数体,可以省略大括号和
return关键字,非常适合短回调场景(比如数组的map/filter方法)。
再回头看你的示例代码
第一个<script>块里,你在const makeHero声明之前就尝试把它作为回调传给addEventListener,此时makeHero还处于暂时性死区,所以浏览器会抛出ReferenceError: Cannot access 'makeHero' before initialization。
而第二个<script>块里,你先声明了makeHero,再调用addEventListener,此时变量已经完成初始化,所以能正常绑定事件。
如果把箭头函数换成传统函数声明,不管调用顺序如何,都能正常运行——这就是函数提升带来的差异。
内容的提问来源于stack exchange,提问作者Aboagye
相关产品推荐
相关产品推荐

