1JavaScript运行原理1.1浏览器工作原理JavaScript代码在浏览器中是如何执行的?1.2浏览器内核那么,向服务器请求相关文件并下载后,解析我们的js文件是干什么的呢?答案是浏览器内核。其实我们常说的浏览器内核就是指浏览器的布局引擎:布局引擎又叫浏览器引擎、页面渲染引擎或模板引擎。有不同的内核GeckoTridentWebkitBlink1.3浏览器渲染过程如果在这个过程执行过程中,在HTML解析时遇到JavaScript标签,怎么办?它将停止解析HTML并加载和执行JavaScript代码。那么谁来执行JavaScript代码呢?JavaScript引擎1.4JavaScript引擎为什么我们需要JavaScript引擎?高级编程语言需要转换成最终的机器指令来执行。其实我们写的JavaScript不管是交给浏览器还是交给Node去执行,都需要CPU去执行。CPU只懂自己的指令集,只能执行机器语言。由CPU执行,需要JavaScript引擎来帮助我们将JavaScript代码翻译成CPU指令才能执行。WebKit就是一个例子。WebKit实际上由两部分组成:WebCore:负责HTML解析、布局、渲染等JavaScriptCore:解析和执行JavaScript代码小程序类似,将代码分为两层:Webview渲染层:负责渲染HTML结构和其他JsCore逻辑层:负责解析和执行JavaScript代码1.6V8引擎官方定义:V8是谷歌开源的用C++编写的高性能JavaScript和WebAssembly引擎,用于Chrome和Node.js,可用于多种不同的V8运行在操作系统上可以独立运行或嵌入到任何C++应用程序中。V8引擎本身的源代码非常复杂,大约有100w行C++代码。通过了解它的架构,我们可以知道它是如何执行JavaScript的:Parse模块:进行词法分析和语法分析,将代码转化为AST(抽象语法树),因为解析器并不直接理解JS代码。如果函数没有被调用,它不会被转换成AST的PArse的V8官方文档:https://v8.dev/blog/scannerIgnitionInterpreter:将AST转换成ByteCode(字节码),收集TurboFan优化需要的信息(比如函数参数的类型信息,有了Type就可以进行真正的操作)如果函数只被调用一次,Ignition会执行解释执行ByteCodepIgnition的V8官方文档:https://v8.dev/blog/ignition-interpreter字节码是跨平台的,所以运行时CPU会把字节码转换成相关平台的汇编代码,然后转换成CPU指令。TurboFan编译器:可以将字节码编译成CPU可以直接执行的机器码。如果一个函数被多次调用,会被标记为热点函数,会被TurboFan转换成优化后的机器码,提高代码的执行性能,但实际上机器码会还原为ByteCode,因为如果函数后续执行过程中类型发生变化(比如sum函数本来是作为数字类型执行的,后来作为字符串类型执行),之前优化的机器码无法正确处理运算,会被逆向转换intobytecode(Deoptimization)TurboFan的V8官方文档:https://v8.dev/blog/turbofan-jit1.7V8执行过程详解JavaScript源码是如何解析(parseprocess)的?Blink(kernel)将JS代码交给V8引擎,Stream获取JS代码并进行编码转换Scanner(扫描器)会进行词法分析(lexicalanalysis),词法分析将代码转化为token,然后token通过Parser和Preparser,转换成AST树Parser是直接将token转换成AST树结构。PreParser称为预解析。为什么需要预解析?因为并不是所有的JavaScript代码都会在一开始就被执行,解析所有的代码势必会影响网页的运行效率,所以V8引擎实现了LazyParsing(延迟解析)的解决方案,它的工作将不需要函数的功能是预解析的,即只解析暂时需要的内容。只有在调用函数时才会生成函数的完整分析。AST树只会被Ignition转换成字节码。之后的过程就是代码执行过程。
