函数声明如何影响变量提升?两段未调用内部函数的JS代码输出不同
问题原因分析
这个差异是JavaScript的作用域规则+函数声明提升机制导致的,和内部函数是否被调用无关。
第一段代码输出2的原因
var a = 1; function foo(){ a= 2; } foo(); console.log(a); // 2
foo函数内部没有声明过名为a的变量,因此执行a=2时,会沿着作用域链向上查找,找到全局作用域下的a,将其值从1修改为2。最终console.log打印的是全局的a,所以输出2。
第二段代码输出1的核心原因
var a = 1; function foo(){ a= 2; function a(){ a = 3; } } foo(); console.log(a); // 1
进入foo函数作用域时,JS会先在预编译阶段处理所有声明:
- 函数声明
function a(){}会被优先提升到foo作用域的最顶端,此时foo作用域内已经存在一个名为a的局部变量,值为这个函数对象 - 执行阶段运行
a=2时,因为当前作用域已经有局部变量a,所以只会把局部的a从函数对象修改为数值2,完全不会触及全局作用域的a - 全局的
a始终没有被修改,保留初始值1,所以最终打印结果为1
函数声明对变量提升的影响机制
- JS执行代码分为两个阶段:预编译阶段(处理所有声明操作)、执行阶段(按顺序运行代码逻辑)
- 同作用域下,函数声明的提升优先级高于var变量声明,会先被注册到作用域中,同时直接赋值为对应的函数对象
- 如果同一作用域存在同名的函数声明和var变量声明,var的声明会被自动忽略(因为同名变量已经被函数声明注册过了)
- 函数声明提升是在预编译阶段完成的,和执行阶段是否调用该函数没有任何关系,只要函数声明写在作用域内,就会触发提升
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

