读书笔记|JavaScript中的变量提升、编译阶段和执行阶段
创始人
2025-05-30 13:37:42
0

前言

原文来自于:浏览器工作原理与实践:07|变量提升:JavaScript代码是按顺序执行的吗?

本文属于个人读书笔记总结,好记性不如烂笔头,学到的东西通过自己的总结后记录下来的才算是自己的知识。

我们都知道,JavaScript有很多语法糖或者语法坑,什么闭包、this对象,网上一查一大把,但很多文章讲的都是“是什么”或者“怎么样”,很少会讲“为什么”,直到我学了这个课程《浏览器工作原理与实践》,从机制上去理解这些知识,瞬间就悟了。有兴趣的可以去极客时间看看这个课程。

正文

一、变量提升

先来看两段代码:

showName()
console.log(myname)
var myname = '极客时间'
function showName() {console.log('函数showName被执行');
}

结果:函数能正常调用,但是变量输出却是undefined

 如果我们把第三行的变量定义去掉

showName()
console.log(myname)
function showName() {console.log('函数showName被执行');
}

结果则是:myname没有定义

 

 之所以会有这样的结果,就是因为变量提升机制


所谓的变量提升,是指在JavaScript代码执行过程中,JavaScript引擎把变量的声明部分和函数的声明部分提升到代码开头的“行为”。变量被提升后,会给变量设置默认值,这个默认值就是我们熟悉的undefined。

这段代码详细可以拆分为两个部分:变量提升部分可执行代码部分

/*
* 变量提升部分
*/
// 把变量 myname提升到开头,
// 同时给myname赋值为undefined
var myname = undefined
// 把函数showName提升到开头
function showName() {console.log('showName被调用');
}/*
* 可执行代码部分
*/
showName()
console.log(myname)
// 去掉var声明部分,保留赋值语句
myname = '极客时间'

用图片来表达则更加清晰:

所以,第一段代码声明了myname,在执行console.log(myname)是myname的值为undefined,输出了undefined;而第二段代码没有声明myname,执行的时候报错了,因为我们不能使用一个未声明的变量。

二、JavaScript代码的执行流程

JavaScript代码的执行可以分为两个阶段:编译阶段和执行阶段。一段JavaScript代码在执行之前需要被JavaScript引擎编译,编译完成之后才会进入执行阶段。

变量提升就是发生在编译阶段。

1、编译阶段

把上面的那段代码细化后,可以得到以下的执行流程细化图:

可以看到,经过编译后会生成两部分内容:执行上下文和可执行代码

执行上下文是JavaScript执行一段代码时的运行环境,比如全局环境的执行上下文,比如调用一个函数,就会进入这个函数的执行上下文。

在执行上下文中存在一个变量环境的对象,该对象中保存了变量提升的内容,比如上面代码中的变量myname和函数showName,都保存在该对象中。

变量环境对象:

VariableEnvironment:myname -> undefined, showName ->function : {console.log(myname)

2、执行阶段

编译阶段可以得到执行上下文和可执行代码,执行阶段就是按顺序一行行处理代码。

showName()    // 函数showName被执行
console.log(myname)    // undefined
myname = '极客时间'
console.log(myname)    // 极客时间
  • 执行showName(),引擎会在变量环境对象中查找该函数,由于存在该函数的引用,所以直接执行该函数,输出“函数showName被执行”
  • 执行console.log(myname),引擎在变量环境对象中查找myname变量,此时myname的值是undefined
  • 执行myname = '极客时间',赋值后变量环境对象中的myname值为'极客时间'
  • 再次执行console.log(myname),输出“极客时间”

三、总结

JavaScript的执行机制:先编译,再执行

  • 编译阶段,先做变量提升,变量和函数声明部分会被存放到变量环境,变量的默认值会被设置为undefined;编译完毕之后,会得到执行上下文和可执行代码;
  • 执行阶段,一行行执行“可执行代码”,JavaScript引擎会从变量环境中查找自定义的变量和函数。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...