JavaScript函数重声明与提升:两种name定义为何执行结果不同?
函数覆盖差异的原因解析
核心前提
浏览器会按script标签的顺序从上到下执行代码,所有顶级作用域的变量、函数都会挂载到全局作用域中。
第一种情况:second.js使用const name = "Zaptec"
当second.js执行时,第一行const name = "Zaptec"会尝试在全局作用域声明新的const变量name,但first.js已经用const声明过同名全局变量。
- const/let不允许重复声明,这属于语法错误,会直接导致second.js代码终止执行,后续的
function greeting()定义根本没机会被解析和挂载到全局作用域。 - 因此全局作用域中保留的仍是first.js定义的
greeting函数,调用时自然执行第一个版本。
第二种情况:second.js使用name = "Zaptec"
second.js的执行分为两个阶段:
- 执行上下文创建阶段(提升):扫描到
function greeting()声明时,会直接将这个函数挂载到全局作用域,覆盖掉first.js定义的greeting函数。 - 代码执行阶段:执行
name = "Zaptec"时,由于name是first.js用const声明的常量,不允许重新赋值,此时会抛出TypeError,但这个错误是在函数已经被覆盖之后才触发的。
- 即便second.js执行报错,浏览器仍会继续执行后续的script标签,第三个script中的
greeting()调用会使用已经被覆盖的second.js版本的函数。
内容的提问来源于stack exchange,提问作者mahmoud mirghani
相关产品推荐
相关产品推荐

