练手题
getAge();
console.log(age);
var age = 10;
function getAge() {
console.log(age);
}
console.log(age);
这是一道基础题,由于 变量提升 执行函数getAge和输出变量age时代码执行并不会报错。
变量提升将变量的声明和赋值拆分为2个动作,以var age = 10;为例,实际执行过程如下:
总结:
JS 代码执行过程中,JS引擎把变量的声明部分和函数的声明部分提升到代码开头。变量被提升后,会给变量设置默认值
undefined。
JS 代码的执行流程
变量提升在什么阶段执行的呢?答案是编译阶段。
JS代码在执行之前需要被 JS引擎编译,编译完成之后,进入执行阶段。
整体流程如下图所示:
编译阶段
JS代码经过编译阶段之后,会得到执行上下文和执行代码,其中执行上下文又包含变量环境和词法环境,变量环境中存放的就是声明的变量。
执行上下文是 JavaScript 执行一段代码时的运行环境,比如调用一个函数,就会进入这个函数的执行上下文,确定该函数在执行期间用到的诸如 this、变量、对象以及函数等。
以上代码经过编译过程如下图所示:
详细分析以下编译过程:
- 第1、2、7行代码无声明操作,无需做处理;
- 第3行代码使用
var声明变量,JS引擎在变量环境中创建一个age属性,并赋值为undefined; - 第4行代码定义了一个函数,JS引擎将函数定义存储到堆中,并在变量环境中创建一个
getAge属性指向函数定义所在的堆位置。 - 对于声明以外的代码及可执行代码,JS引擎会编译为字节码,模拟代码如下:
getAge();
console.log(age);
age = 10;
console.log(age);
对于重名的函数,后面的函数会覆盖前面的函数,变量环境中存储的是最新的函数定义的堆地址。
执行阶段
得到了执行上下文和可执行代码后,JS引擎可以执行代码,详细分析下执行过程:
getAge()JS引擎从执行上下文中查询到对应函数的地址并执行,getAge需要用到变量age,从执行上下文中获取age变量的值,此时age未赋值,输出为undefined;console.log(age)同上,此时age未赋值,输出为undefined;age = 10此时找age变量并赋值为10;console.log(age)此时age已赋值,输出为10;
总结
以上内容详细分析JS代码从编译到执行的详细过程,大家需要记住以下两个知识点:
-
变量提升机制: 在 JavaScript 中,变量和函数的声明会被提升到代码的顶部,但赋值操作保留在原位置。这意味着在代码执行前,变量已经被声明并初始化为
undefined,而函数则被存储在内存中。 -
编译与执行阶段: JavaScript 代码的执行分为编译阶段和执行阶段。编译阶段处理变量和函数的声明,生成执行上下文。执行阶段则根据执行上下文执行代码,处理变量的赋值和函数调用。