记住两点:
- Javascript是一门单线程语言
- Javascript的执行机制是Event Loop(事件循环)
执行上下文和执行栈
执行上下文:
- 全局执行上下文:只有一个,浏览器中的全局对象就是 window 对象,this 指向这个全局对象。
- 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文。
- Eval 函数执行上下文: 指的是运行在
eval
函数中的代码,很少用而且不建议使用
执行栈:也叫调用栈,具有 LIFO(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文。首次运行JS代码时,会创建一个全局执行上下文并Push到当前的执行栈中。每当发生函数调用,引擎都会为该函数创建一个新的函数执行上下文并Push到当前执行栈的栈顶。根据执行栈LIFO规则,当栈顶函数运行完成后,其对应的函数执行上下文将会从执行栈中Pop出,上下文控制权将移到当前执行栈的下一个执行上下文
如下图示例:
执行上下文分创建为两个阶段:
- 创建阶段:
1. 确定this
的值,也被称为This Binding
2.LexicalEnvironment
(词法环境) 组件被创建
3.VariableEnvironment
(变量环境) 组件被创建 - 执行阶段:此阶段,完成对所有变量的分配,最后执行代码。如果
Javascript
引擎在源代码中声明的实际位置找不到let
变量的值,那么将为其分配undefined
值
进程与线程
进程:CPU
是计算机的核心,承担所有的计算任务,进程是CPU
资源分配的最小单位,字面意思是进行中的程序,可以将它理解为一个可以独立运行且拥有自己的资源空间的任务程序
进程
包括运行中的程序和程序所使用到的内存和系统资源
线程:是CPU
调度的最小单位,线程
是建立在进程
的基础上的一次程序运行单位,通俗点解释线程就是程序中的一个执行流,一个进程
可以有多个线程
一个进程
中只有一个执行流称作单线程
,即程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行
一个进程
中有多个执行流称作多线程
,即在一个程序中可以同时运行多个不同的线程来执行不同的任务, 也就是说允许单个程序创建多个并行执行的线程来完成各自的任务
进程与线程的区别:
- 进程是操作系统分配资源的最小单位,线程是程序执行的最小单位
- 一个进程由一个或多个线程组成,线程可以理解为是一个进程中代码的不同执行路线
- 进程之间相互独立,但同一进程下的各个线程间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号)
- 调度和切换:线程上下文切换比进程上下文切换要快得多
Javascript Engine:JS引擎,负责解释并编译代码,让它变成能交给机器运行的代码
Javascript runtime:Js运行环境,主要提供一些对外调用的接口 。比如浏览器环境:window
、 DOM
,还有Node.js
环境:require
、export
执行机制
JS执行机制分为同步任务和异步任务:
- 同步任务直接进入主线程进行执行
- 异步任务又分为
宏任务
与微任务
,异步任务必须指定回调函数
,所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务进入Event Table后,当指定的事情完成了,就将异步任务加入Event Queue,等待主线程上的任务完成后,就执行Event Queue里的异步任务,也就是执行对应的回调函数
常见的宏任务:
- 主代码块
- setTimeout
- setInterval
- setImmediate ()-Node
- requestAnimationFrame ()-浏览器
- 等等…
常见的微任务:
- process.nextTick ()-Node
- Promise.then()
- catch
- finally
- Object.observe
- MutationObserver
- 等等…
最后,附上完成的执行机制图解:
首先,整体的script
(作为第一个宏任务)开始执行的时候,会把所有代码分为同步任务
、异步任务
两部分
同步任务会直接进入主线程依次执行
异步任务会再分为宏任务和微任务
宏任务进入到Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中
微任务也会进入到另一个Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中
当主线程内的任务执行完毕,主线程为空时,会检查微任务的Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务
上述过程会不断重复,这就是Event Loop,比较完整的事件循环