浏览器中的JavaScript运行机制
JavaScript是单线程,可以通过异步来实现多线程
目录
- 浏览器中的JavaScript运行机制
- ESMAScript和JavaScript的关系
- JS Engine(JS引擎)
- Context(执行上下文)
- Call Stack(调用栈)
- Event Loop(事件循环)
- JavaScript运行机制
- 浏览器的线程
ESMAScript和JavaScript的关系
- 客户端:浏览器里面的JavaScript里面包括ESMAScript和WEBAPI
- 服务端:服务端里面的为node.js里面包括ESMAScript和NodeAPI
- JavaScript其实就是一个称呼,其语言本身还是ESMAScript语言
JS Engine(JS引擎)
JavaScript引擎就是用来执行JS代码,通过解释器将代码解释成可执行的机器码让计算机去执行该代码实现的内容。
引擎主要包括:
- Heap(堆):JS引擎中给对象(引用类型)分配内存空间的放在对里
- Stack(栈):储存着JavaScript正在执行的任务(也就是帧),后进先出
回到顶部 目录
Context(执行上下文)
JavaScript的运行环境,比如调用一个函数的时候就会进入函数的执行上下文
JavaScript中有三种执行上下文类型:
- 全局执行上下文:简单来说就是在js文件里面编写的代码在全局作用域下的GPT改写。
- 创建一个全局window对象(浏览器的情况下)
- 设置this的值等于这个全局对象window
- 一个程序只会有一个全局执行上下文
- 函数执行上下文:当一个函数被调用时,JavaScript引擎会先为该函数创建一个新的执行上下文
- Eval函数执行上下文:在执行eval函数的时候,JavaScript引擎也会在eval内部创建一个属于它自己的执行上下文
Call Stack(调用栈)
JavaScript引擎是利用栈的结构(后进先出)来管理执行上下文的
在执行上下文创建好后,JavaScript引擎将执行上下文添加到栈里,通常把这种管理执行上下文的栈称为执行上下栈,简称调用栈
浏览器中查看调用栈的方法:
- 打断点
- console.trace()
栈的溢出:当执行上下文把栈占满了还有执行上下文没有处理就是溢出,正常情况下是不会出现的
回到顶部 目录
Event Loop(事件循环)
JavaScript在执行代码的过程中出了调用栈还有任务队列来解决一些代码
任务队列(宏任务(macro-task/task) + 微任务(micro-task/jobs))
宏任务大概包括:
- (整体代码)
- setTimeout
- setInterval
- setlmmediate
- I/O
- UI rendering
微任务大概包括:
- process.nextTick
- Promise
- Async/Await
- MutauionObsetver(H5新特征)
JavaScript运行机制
JavaScript引擎调用栈,把栈里面的内容执行完以后,在到任务队列里面先执行队列的所有任务,如果没有微队列,将执行宏任务,在执行宏任务中产生的微任务,若微任务中又产生了微任务,这继续执行微任务直到执行完毕,在回到宏任务
async function async1(){
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2 end')
}
async1()
setTimeout(function(){
console.log('setTimeout end')
},0);
new Promise(resolve => {
console.log('Promise');
resolve();
}).then(function(){
console.log('Promise1');
}).then(function(){
console.log('Promise2');
});
浏览器的线程
- JavaScript线程(主线程):负责执行栈顶的代码
- GUI线程:负责绘制HTML页面的
JavaScript线程和GUI线程会相互等待 - 事件监听线程:负责监听各种事件
- 计时线程:负责定时器的
- 网络线程:各种网络请求