新手入门带你学习JavaScript引擎运行原理

JS引擎 — 一个读取代码并运行的引擎,没有单一的“JS引擎”;,每个浏览器都有自己的引擎,如谷歌有V。

作用域 — 可以从中访问变量的“区域”。

词法作用域— 在词法阶段的作用域,换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变。

块作用域 — 由花括号{}创建的范围

作用域链 — 函数可以上升到它的外部环境(词法上)来搜索一个变量,它可以一直向上查找,直到它到达全局作用域。

同步 — 一次执行一件事, “同步”引擎一次只执行一行,JavaScript是同步的。

异步 — 同时做多个事,JS通过浏览器API模拟异步行为

事件循环(Event Loop) - 浏览器API完成函数调用的过程,将回调函数推送到回调队列(callback queue),然后当堆栈为空时,它将回调函数推送到调用堆栈。

堆栈 —一种数据结构,只能将元素推入并弹出顶部元素。 想想堆叠一个字形的塔楼; 你不能删除中间块,后进先出。

— 变量存储在内存中。

调用堆栈 — 函数调用的队列,它实现了堆栈数据类型,这意味着一次可以运行一个函数。 调用函数将其推入堆栈并从函数返回将其弹出堆栈。

执行上下文 — 当函数放入到调用堆栈时由JS创建的环境。

闭包 — 当在另一个函数内创建一个函数时,它“记住”它在以后调用时创建的环境。

垃圾收集 — 当内存中的变量被自动删除时,因为它不再使用,引擎要处理掉它。

变量的提升— 当变量内存没有赋值时会被提升到全局的顶部并设置为undefined。

this —由JavaScript为每个新的执行上下文自动创建的变量/关键字。

调用堆栈(Call Stack)

看看下面的代码:

var myOtherVar = 10 function a() { console.log('myVar', myVar) b() } function b() { console.log('myOtherVar', myOtherVar) c() } function c() { console.log('Hello world!') } a() var myVar = 5

有几个点需要注意:

变量声明的位置(一个在上,一个在下)

函数a调用下面定义的函数b, 函数b调用函数c

当它被执行时你期望发生什么? 是否发生错误,因为b在a之后声明或者一切正常? console.log 打印的变量又是怎么样?

以下是打印结果:

"myVar" undefined "myOtherVar" 10 "Hello world!"

来分解一下上述的执行步骤。

1. 变量和函数声明(创建阶段)

第一步是在内存中为所有变量和函数分配空间。 但请注意,除了undefined之外,尚未为变量分配值。 因此,myVar在被打印时的值是undefined,因为JS引擎从顶部开始逐行执行代码。

函数与变量不一样,函数可以一次声明和初始化,这意味着它们可以在任何地方被调用。

所以以上代码看起来像这样子:

var myOtherVar = undefined var myVar = undefined function a() {...} function b() {...} function c() {...}

这些都存在于JS创建的全局上下文中,因为它位于全局空间中。

在全局上下文中,JS还添加了:

全局对象(浏览器中是 window 对象,NodeJs 中是 global 对象)

this 指向全局对象

2. 执行

接下来,JS 引擎会逐行执行代码。

myOtherVar = 10在全局上下文中,myOtherVar被赋值为10

已经创建了所有函数,下一步是执行函数 a()

每次调用函数时,都会为该函数创建一个新的上下文(重复步骤1),并将其放入调用堆栈。

function a() { console.log('myVar', myVar) b() }

如下步骤:

创建新的函数上下文

a 函数里面没有声明变量和函数

函数内部创建了 this 并指向全局对象(window)

接着引用了外部变量 myVar,myVar 属于全局作用域的。

接着调用函数 b ,函数b的过程跟 a一样,这里不做分析。

下面调用堆栈的执行示意图:

新手入门带你学习JavaScript引擎运行原理

创建全局上下文,全局变量和函数。

每个函数的调用,会创建一个上下文,外部环境的引用及 this。

函数执行结束后会从堆栈中弹出,并且它的执行上下文被垃圾收集回收(闭包除外)。

当调用堆栈为空时,它将从事件队列中获取事件。

作用域及作用域链

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/56a11a9d8eb55ba8d0afa55fac5e9db5.html