人人都看得懂的JS运行机制(中)

简介: 本文是以作者自己理解的思路拆分的JS运行机制,见解有限难免疏漏,欢迎留言勘误、交流。

JS引擎


根据上文的描述,JS源代码是需要经过JS引擎解析、转化之后才执行的。


通常认为,JS引擎主要有两部分组成:


  • 内存堆 引用类型实际值、内存分配的地方


  • 调用栈 基本类型存储、引用类型地址名存储、代码逻辑执行的地方


源代码进入JS引擎之后,顺序读取代码,按照变量声明、函数执行等不同规则,分配到堆、或者栈内。



内存堆


存储项目引用类型数据的地方, 系统分配的内存,


JS中的引用类型数据,实际值是零散地存在这里面的


事实上,引用类型的存储是分为2部分存储的:


  • 真实值存储在内存中, 是系统根据自身情况,内存区哪里有合适的位置,就分配在哪里,没有严格的顺序的,因此说是零散的


  • 真实值所在的物理内存地址,这个值是以基本值的形式存储在栈内的


平时代码中的引用类型赋值,就是仅仅把栈内存储的内存地址赋给新变量,就相当于是告诉新变量该值在内存中的位置,需要的时候去取就行,并不是把真正的值传递过去,内存中该值是只有一份的。这也是引起引用问题的原因


执行栈


执行栈,是代码中实际逻辑语句执行的地方,同时项目运行过程中产生的基本类型的值也是存在此处。


引擎会把代码分成一个个可执行单元,然后依次进入执行栈,被执行

那么可执行单元是什么?


可执行单元,标准的说法是执行上下文


JS中,执行上下文可以是以下几种:


  • Global code   ----->  全局执行上下文


  • Function code   ----->  函数执行上下文


  • Eval code   ----->  eval函数执行上下文


这些东西有什么共同点?


全局代码可以看作是一个IIFE(立即执行函数),


函数就是通俗意义上的函数


eval 是可以把传入字符串执行的函数


函数啊, 全部都是函数啊


因此我们可以粗略的理解为: 执行栈里面的东西,都是一个个函数调用


  • 首先是入口文件的全部JS代码作为一个IIFE,最先入栈被调用


  • 然后在实际执行过程中,调用了其他函数,就会顺次被压入栈内执行


因此, JS引擎的示意图可以更新为如下:



单线程


JS是单线程的。  地球人都知道。


什么意思?


JS引擎中,代码执行是在调用栈的里发生的。


栈是一种LIFO(last in first out 后进先出)的数据结构。


只有栈顶的函数会被处理, 处理完成之后弹出栈, 后面的进入栈顶,再被执行...

举个🌰:


如下的JS文件


function first() {
  second();  
}
function second() {  
  console.log('log fn');  
}
first();
... // 后续操作



JS引擎处理这段代码的步骤如下 (只关注函数调用)


  1. 整段代码作为一个IIFE,入栈, main()函数调用进入栈顶,开始执行


  1. 遇到first函数调用, first函数进入栈顶,开始进入first函数体执行 (此时main函数还未执行完毕)


  1. 进入first函数体之后,遇到调用second函数, 把second函数压入栈顶,进入second函数体执行


  1. 进入second函数体之后,遇到console.log函数调用, 把console.log压入栈顶执行


  1. console.log函数打印完毕之后,执行结束, 弹出栈顶


  1. 此时栈顶是second函数,继续执行second函数体中,console.log之后的代码,发现没有可执行代码了,OK,那就宣告second执行完毕,弹出


  1. 此时first函数进入栈顶,那就执行first函数体中,second函数调用之后的代码,发现空空如也,那么first函数执行完毕,弹出


  1. 栈顶main函数执行后续代码


因此JS单线程,指的是在JS引擎中,解析执行JS代码的调用栈是唯一的,所有的JS代码都在这一个调用栈里按照调用顺序执行,不能同时执行多个函数


相关文章
|
3月前
|
存储 JavaScript 前端开发
深入理解JavaScript中的事件循环(Event Loop):机制与实现
【10月更文挑战第12天】深入理解JavaScript中的事件循环(Event Loop):机制与实现
151 3
|
2月前
|
Web App开发 JSON JavaScript
Node.js 中的中间件机制与 Express 应用
Node.js 中的中间件机制与 Express 应用
|
4月前
|
JavaScript 安全 前端开发
乾坤js隔离机制
乾坤js隔离机制
|
2月前
|
JavaScript 安全 中间件
深入浅出Node.js中间件机制
【10月更文挑战第36天】在探索Node.js的奥秘之旅中,中间件的概念如同魔法一般,它让复杂的请求处理变得优雅而高效。本文将带你领略这一机制的魅力,从概念到实践,一步步揭示如何利用中间件简化和增强你的应用。
|
2月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
385 1
|
2月前
|
消息中间件 JavaScript 中间件
深入浅出Node.js中间件机制
【10月更文挑战第24天】在Node.js的世界里,中间件如同厨房中的调料,为后端服务增添风味。本文将带你走进Node.js的中间件机制,从基础概念到实际应用,一探究竟。通过生动的比喻和直观的代码示例,我们将一起解锁中间件的奥秘,让你轻松成为后端料理高手。
47 1
|
3月前
|
移动开发 JavaScript 前端开发
【JavaScript】JS执行机制--同步与异步
【JavaScript】JS执行机制--同步与异步
35 1
|
3月前
|
JSON JavaScript 中间件
深入浅出Node.js中间件机制
本文将带你探索Node.js中一个核心概念——中间件机制。我们将通过浅显的语言和生动的比喻,揭示中间件如何作为请求和响应之间的“交通枢纽”,在应用程序中起到至关重要的作用。从基础原理到实际应用,你将了解到中间件不仅简化了代码结构,还提高了开发效率,是Node.js开发不可或缺的一部分。
65 1
|
3月前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
45 0
|
4月前
|
前端开发 JavaScript Java
JavaScript的运行原理
JavaScript 的运行原理包括代码输入、解析、编译、执行、内存管理和与浏览器交互几个步骤。当打开网页时,浏览器加载 HTML、CSS 和 JavaScript 文件,并通过 JavaScript 引擎将其解析为抽象语法树(AST)。接着,引擎将 AST 编译成字节码或机器码,并在执行阶段利用事件循环机制处理异步操作,确保单线程的 JavaScript 能够高效运行。同时,JavaScript 引擎还负责内存管理和垃圾回收,以减少内存泄漏。通过与 DOM 的交互,JavaScript 实现了动态网页效果,提供了灵活且高效的开发体验。

热门文章

最新文章