探究javascript的运行时

前言

我们天天写业务,公司小,业务简单,经验不值钱,出来面试被说没亮点,写个业务都要问原理,如果没答好,就开始以下场景:

面试官:“你有什么要问我的吗?”
你:“额,我,我没什么要问的。。。”

不,其实你不是这样子的,你不想这么憋屈的离开,你不想就这样辛辛苦苦跑过来被两三句话打发掉!

所以,开启绝地反击模式:

面试官:“你有什么要问我的吗?”
你:“js的运行时是怎么样的?”
面试官:“我。。。”

运行时解析

如下代码

var a = 1
let b = 2
const c = {k: 3}

function d () {
  console.log(a)
  var a = 11
  let b = 22
  dd()
}

function dd () {
   console.log(b)
}

d() // 输出啥? undefined 2

如果你是js老手, 一看d()执行结果就知道是a变量提升了打印undefined,dd方法执行打印2,那a为什么会提升呢, 怎么不是打印外面的变量a = 1呢?b怎么不打印22呢?想要弄清楚这些问题,就要了解js的执行机制了。

js运行时有两个阶段:编译阶段、执行阶段。
编译阶段:js通过编译生成执行上下文和可执行代码两部分。
执行阶段:执行可执行代码,输出结果。
可以理解如下图

js运行时

执行上下文是啥?可执行代码又是啥?

执行上下文是 JavaScript 执行一段代码时的运行环境,比如调用一个函数,就会进入这个函数的执行上下文,确定该函数在执行期间用到的诸如 this、变量、对象以及函数等。

可执行代码就是指js引擎可以执行的代码,这些代码可以是【字节码、机器码】。我们写的js代码它看不懂,也不会执行,它要先把js编译成字节码、机器码才行。

其实不管是什么高级语言代码都要编译才能执行,后面再说。

了解了这两个概念还不够,执行上下文里面有哪些内容?可以如下图表示


执行上下文.png

看上图,这是编译阶段的输出,可以了解到一些重要信息:
变量环境:执行上下文中var 声明的变量,且赋值默认值undefined。
词法环境:执行上下文中let const声明的变量,这是解决变量提升问题,重点这是在es6加入的,es5并没有词法环境。
outer: 外部引用,其实在每个执行上下文中,都包含了一个外部引用,用来指向外部的执行上下文,我们把这个外部引用称为 outer。在js中有全局执行上下文、函数上下文之说,每个上下文的外部引用都是在编译时决定的,这个和代码的编译时的位置有关,也称为词法作用域。词法作用域就是指作用域是由代码中函数声明的位置来决定的,所以词法作用域是静态的作用域,通过它就能够预测代码在执行过程中如何查找标识符。理解可以参考下图

词法作用域,编译时根据位置确定

this: this是一套和作用域无关的独立机制,这个你可以另外找到相关文章深入理解。

变量提升其实就是函数运行的编译阶段,把所有var声明的变量统一提升到该作用域“顶部”, 并赋默认值undefined。

所以执行d()函数的时候,相当于以下流程,先编译再执行

var a = undefined
console.log(a)
a = 11

而dd()执行的时候其实就是按照上面说的,由于dd上下文没有声明b变量,根据作用域链查找外部引用,直到首次找到b,而作用域在编译阶段就确定了外部引用。具体可以参考下图:

d方法运行时.png

所以,就例子而言无论d方法还是dd方法,它们的外部引用都是指向全局上下文,在执行阶段,如果发现函数作用域没有变量声明就会沿着作用域往外部引用查找。

总结一下
1、js运行时有两个阶段:编译阶段 和 执行阶段
2、变量提升的根本原因是js在编译阶段确定的
3、执行上下文有变量环境与词法环境,变量环境存储var声明的变量,词法环境存储let cosnt声明的变量。
4、每个作用域的外部引用在编译阶段根据代码的位置确定。

v8引擎角度看javascript运行时

上面说到js运行时有编译阶段 和 执行阶段两个阶段,那么再从js引擎的角度来看,这是怎么一回事。

首先先了解一些概念:

编译器和解释器
之所以存在编译器和解释器,是因为机器不能直接理解我们所写的代码,所以在执行程序之前,需要将我们所写的代码“翻译”成机器能读懂的机器语言。

按语言的执行流程,可以把语言划分为编译型语言和解释型语言。编译型语言在程序执行之前,需要经过编译器的编译过程,并且编译之后会直接保留机器能读懂的二进制文件,这样每次运行程序时,都可以直接运行该二进制文件,而不需要再次重新编译了。比如 C/C++、GO 等都是编译型语言。而由解释型语言编写的程序,在每次运行时都需要通过解释器对程序进行动态解释和执行。比如 Python、JavaScript 等都属于解释型语言。

解释器、编译器 语言流程

了解上面的概念之后,v8引擎就是走的基于解释器的路线,但是又与它不同,是一个改进版。具体如下图

v8引擎处理代码流程.png

从图中可以看出v8是解释器、编译器一起用了的。

通常,如果有一段第一次执行的字节码,解释器 Ignition 会逐条解释执行。解释器 Ignition 除了负责生成字节码之外,它还有另外一个作用,就是解释执行字节码。在 Ignition 执行字节码的过程中,如果发现有热点代码(HotSpot),比如一段代码被重复执行多次,这种就称为热点代码,那么后台的编译器 TurboFan 就会把该段热点的字节码编译为高效的机器码,然后当再次执行这段被优化的代码时,只需要执行编译后的机器码就可以了,这样就大大提升了代码的执行效率。

回到上面的js运行时两个阶段,编译阶段和执行阶段,编译阶段就是源码 ->AST -> 字节码。执行阶段就是基于字节码、机器码执行。

最后

好了,以上就是javascript运行时的内容,了解这一过程希望对你开发过程有所帮助。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345