变量提升的工作原理?函数与变量提升的差异及代码执行疑问
变量提升的工作原理及函数、变量提升的区别
咱们先从变量提升的核心逻辑说起:JavaScript引擎在执行代码前,会先对当前作用域的代码做一次预编译处理——简单说就是把所有var声明的变量和函数声明,“提前”移动到当前作用域的最顶部。但要注意两个关键细节:
var变量只有声明被提升,赋值操作会留在原地,而且提升后的变量会被默认初始化为undefined。- 函数声明是整个函数(包括函数体)都被提升,所以在作用域内任何位置都能直接调用这个函数。
函数提升与变量提升的核心区别
- 优先级不同:当作用域内出现同名的函数声明和
var变量声明时,函数提升的优先级更高,会覆盖变量的声明(但如果变量有赋值操作,赋值会在执行阶段覆盖函数)。 - 提升内容不同:函数提升是完整的函数体,变量提升只是声明,默认值为
undefined。
两段代码的执行分析
第一段代码:返回function的原因
function scope() { return hosting; function hosting() { var hosting = '15'; } var hosting = 12; } console.log(typeof scope())
在预编译阶段,JS引擎会完成两个操作:
- 把函数声明
function hosting()完整提升到scope作用域的最顶部; - 把
var hosting的声明也提升,但因为函数提升优先级更高,此时hosting指向的是那个函数,变量声明被函数覆盖。
当代码执行到return hosting时,直接返回了被提升后的函数,所以typeof结果是function。后面的变量赋值var hosting = 12根本没机会执行,因为return已经跳出了函数。
第二段代码:为什么不返回number
function scope() { return hosting; var hosting = 12; } console.log(typeof scope())
预编译阶段,只有var hosting的声明被提升到作用域顶部,此时hosting被初始化为undefined。
执行代码时,先遇到return hosting,此时hosting还没执行到赋值语句var hosting = 12(赋值在return后面,完全没机会运行),所以返回的是undefined,typeof结果自然是undefined,而不是number。
你提到用let可以避免这种情况,是因为let声明的变量不存在变量提升,而且存在“暂时性死区”——在声明前访问let变量会直接抛出错误,从根源上避免了这种混淆。
内容的提问来源于stack exchange,提问作者Selva Ganapathi
相关产品推荐
相关产品推荐

