JavaScript变量提升优先级:变量与函数谁先被提升?
理解JavaScript变量提升:拆解你的代码执行过程
别慌,我们把代码拆成编译阶段和执行阶段一步步分析,你就能搞懂第二个f()调用的结果了。
首先先贴出你的代码方便对照:
var alpha = 'alpha'; var beta = 'beta'; f(); // 你说输出beta?实际应该是alpha,后面会解释 var f = function f1() { console.log(beta); }; function f() { console.log(alpha); } f(); // 你说输出alpha?实际应该是beta
第一步:编译阶段(变量提升的核心)
JavaScript引擎在执行代码前,会先扫描整个作用域处理所有声明,这就是变量提升的本质:
- 所有
var声明的变量会被提升到作用域顶部,初始值为undefined:比如alpha、beta、f都会被先声明,值都是undefined。 - 函数声明会被完整提升(声明+定义),而且优先级比
var变量高:所以同名的函数声明function f() { console.log(alpha); }会直接覆盖var f的初始undefined,此时f指向这个打印alpha的函数。
此时作用域的状态是:
alpha: undefinedbeta: undefinedf: function f() { console.log(alpha); }
第二步:执行阶段(逐行跑代码)
现在开始逐行执行代码:
var alpha = 'alpha';→ 给alpha赋值为'alpha'var beta = 'beta';→ 给beta赋值为'beta'f();→ 此时f还是编译阶段提升的那个函数,执行它会打印alpha的值,也就是'alpha'(这里你说输出beta,大概率是代码顺序写反了,或者你混淆了函数声明和表达式的提升)var f = function f1() { console.log(beta); };→ 这是变量赋值(声明已经在编译阶段处理完了),所以f被重新赋值为这个新的函数表达式function f() { console.log(alpha); }→ 这是函数声明,编译阶段已经处理过了,执行阶段会直接跳过这一行,不会改变f的值f();→ 此时f已经被步骤4的赋值覆盖,执行这个新函数会打印beta的值,也就是'beta'
你的困惑点在哪里?
你可能误以为后面的函数声明function f()会在执行阶段重新覆盖f的值,但实际上函数声明只在编译阶段处理一次,执行阶段遇到函数声明会直接忽略。步骤4的赋值操作已经把f替换成了新的函数,所以第二个f()调用的是这个新函数,而不是最初的函数声明。
如果你的实际运行结果和这个分析不符,建议检查代码中函数声明和变量赋值的顺序是否搞反了~
内容的提问来源于stack exchange,提问作者Avernikoz
相关产品推荐
相关产品推荐

