本文解析JavaScript引擎执行代码时的预解析阶段。通过变量与函数声明提升的对比,说明var声明仅提升变量名而保留赋值,函数声明则整体提升。结合代码示例,阐述为何变量未赋值输出undefined,而调用未定义的函数表达式会报错,帮助开发者掌握正确的代码书写顺序。
JavaScript预解析机制:变量与函数提升详解
在深入探讨预解析机制之前,我们先通过两个具体的代码案例来观察现象。
首先,请思考第一个案例的执行结果会是什么?
console.log(num);
var num=10;实际运行结果显示为 undefined。
接着,我们来看第二个案例的输出结果又是多少?
fun();
var fun=function(){
console.log(22);
}显然,这段代码在执行时会抛出错误。
那么,造成这种执行差异的根本原因是什么呢?
JavaScript引擎在执行脚本时,主要分为两个阶段:首先是预解析阶段,随后才是代码执行阶段。
- 在预解析阶段,JavaScript引擎会将当前作用域内所有的 var 变量声明和 function 函数声明提升到作用域的顶部。
- 在代码执行阶段,引擎会严格按照代码书写的顺序,从上至下依次执行。
预解析过程具体包含两个部分:变量预解析(即变量提升)和函数预解析(即函数提升)。
- 变量提升指的是将所有使用 var 声明的变量名提升到当前作用域的最前面,但不会提升变量的赋值操作。
- 函数提升指的是将所有函数声明提升到当前作用域的最前面,但不会执行函数的调用。
基于上述原理,我们可以将第一个案例还原为引擎实际执行的代码形式。
var num;
console.log(num);
num=10;
同样地,第二个案例在预解析后的实际执行代码形式如下。
var fun;
fun();
fun=funciton(){
console.log(22);
}通过对比可以看出,变量 num 虽然被声明但未赋值,因此输出 undefined;而函数表达式 fun 在调用时并未完成赋值,导致调用失败并报错。因此,函数表达式的调用语句必须放置在函数表达式声明语句的下方,否则会导致错误。