JavaScript运行原理

JavaScript运行原理

一. JavaScript如何运行

1.1. Atwood定律

我们先看一下官方对Node.js的定义:

  • Node.js是一个基于V8 JavaScript引擎的JavaScript运行时环境。

但是这句话对于很多人来说,非常笼统:

  • 什么是JavaScript运行环境?
  • 为什么JavaScript需要特别的运行环境呢?
  • 什么又是JavaScript引擎?
  • 什么是V8?

我们先来把这些概念搞清楚,再去看Node到底是什么?

Stack Overflow的创立者之一的 Jeff Atwood 在2007年提出了著名的 Atwood定律:

  • Any application that can be written in JavaScript, will eventually be written in JavaScript.
  • 任何可以使用JavaScript来实现的应用都最终都会使用JavaScript实现。

在这里插入图片描述

但是在发明之初,JavaScript的目的是应用于在浏览器执行简单的脚本任务,对浏览器以及其中的DOM进行各种操作,所以JavaScript的应用场景非常受限。

  • Atwood定律更像是一种美好的远景,在当时看来还没有实现的可能性。
  • 但是随着Node的出现,Atwood定律已经越来越多的被证实是正确的。

但是为了可以理解Node.js到底是如何帮助我们做到这一点的,我们必须了解JavaScript是如何被运行的。

1.2.浏览器内核

我们经常会说:不同的浏览器有不同的内核组成

  • Gecko:早期被Netscape和Mozilla Firefox浏览器浏览器使用;
  • Trident:微软开发,被IE4~IE11浏览器使用,但是Edge浏览器已经转向Blink;
  • Webkit:苹果基于KHTML开发、开源的,用于Safari,Google Chrome之前也在使用;
  • Blink:是Webkit的一个分支,Google开发,目前应用于Google Chrome、Edge、Opera等;
  • 等等…

事实上,我们经常说的浏览器内核指的是浏览器的排版引擎:

  • 排版引擎(layout engine),也称为浏览器引擎(browser engine)、页面渲染引擎(rendering engine)或样版引擎

在这里插入图片描述

但是在这个执行过程中,HTML解析的时候遇到了JavaScript标签,应该怎么办呢?

  • 会停止解析HTML,而去加载和执行JavaScript代码;

当然,为什么不直接异步去加载执行JavaScript代码,而要在这里停止掉呢?

  • 这是因为JavaScript代码可以操作我们的DOM;
  • 所以浏览器希望将HTML解析的DOM和JavaScript操作之后的DOM放到一起来生成最终的DOM树,而不是频繁的去生成新的DOM树;

那么,JavaScript代码由谁来执行呢?

  • JavaScript引擎

1.3.JavaScript引擎

为什么需要JavaScript引擎呢?

  • 事实上我们编写的JavaScript无论你交给浏览器或者Node执行,最后都是需要被CPU执行的;
  • 但是CPU只认识自己的指令集,实际上是机器语言,才能被CPU所执行;
  • 所以我们需要JavaScript引擎帮助我们将JavaScript代码翻译成CPU指令来执行;

比较常见的JavaScript引擎有哪些呢?

  • SpiderMonkey:第一款JavaScript引擎,由Brendan Eich开发(也就是JavaScript作者);
  • Chakra:微软开发,用于IT浏览器;
  • JavaScriptCore:WebKit中的JavaScript引擎,Apple公司开发;
  • V8:Google开发的强大JavaScript引擎,也帮助Chrome从众多浏览器中脱颖而出;

这里我们先以WebKit为例,WebKit事实上由两部分组成的:

  • WebCore:负责HTML解析、布局、渲染等等相关的工作;
  • JavaScriptCore:解析、执行JavaScript代码;

在这里插入图片描述

看到这里,学过小程序的有没有感觉非常的熟悉呢?

  • 在小程序中编写的JavaScript代码就是被JSCore执行的;

在这里插入图片描述
另外一个强大的JavaScript引擎就是V8引擎。

1.4. V8引擎

我们来看一下官方对V8引擎的定义:

  • V8是用C ++编写的Google开源高性能JavaScript和WebAssembly引擎,它用于Chrome和Node.js等。
  • 它实现ECMAScript和WebAssembly,并在Windows 7或更高版本,macOS 10.12+和使用x64,IA-32,ARM或MIPS处理器的Linux系统上运行。
  • V8可以独立运行,也可以嵌入到任何C ++应用程序中。

V8引擎本身的源码非常复杂,大概有超过100w行C++代码,但是我们可以简单了解一下它执行JavaScript代码的原理:

  • Parse模块会将JavaScript代码转换成AST(抽象语法树),这是因为解释器并不直接认识JavaScript代码;
    • 如果函数没有被调用,那么是不会被转换成AST的;
    • Parse的V8官方文档:https://v8.dev/blog/scanner
  • Ignition是一个解释器,会将AST转换成ByteCode(字节码)
    • 同时会收集TurboFan优化所需要的信息(比如函数参数的类型信息,有了类型才能进行真实的运算);
    • 如果函数只调用一次,Ignition会执行解释执行ByteCode;
    • Ignition的V8官方文档:https://v8.dev/blog/ignition-interpreter
  • TurboFan是一个编译器,可以将字节码编译为CPU可以直接执行的机器码;
    • 如果一个函数被多次调用,那么就会被标记为热点函数,那么就会经过TurboFan转换成优化的机器码,提高代码的执行性能;
    • 但是,机器码实际上也会被还原为ByteCode,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执行的是number类型,后来执行变成了string类型),之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码;
    • TurboFan的V8官方文档:https://v8.dev/blog/turbofan-jit

在这里插入图片描述
上面是JavaScript代码的执行过程,事实上V8的内存回收也是其强大的另外一个原因,这里暂时先不展开讨论:

  • Orinoco模块,负责垃圾回收,将程序中不需要的内存回收;
  • Orinoco的V8官方文档:https://v8.dev/blog/trash-talk
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: UniApp 是一个使用 Vue.js 开发跨平台应用的框架。它的运行原理是基于 HBuilderX 编辑器将开发者编写的代码转换成原生平台的代码,然后运行在各个平台上。 首先,开发者使用 HBuilderX 编辑器创建一个 UniApp 项目,并选择所要开发的平台,如微信小程序、App、H5 等。然后,开发者使用 Vue.js 组件和语法编写应用的各个页面和功能。 UniApp 在编译的过程中,通过将开发者编写的代码转换为各个平台的运行代码,使得应用在不同平台上都能够正常运行。例如,对于微信小程序,UniApp 会将代码转换为符合微信小程序标准的 wxml、wxss 和 js 文件;对于 App,UniApp 会将代码转换为原生的 Android 或 iOS 代码。 UniApp 还提供了一套跨平台的 API,使得开发者能够方便地调用原生平台的功能和接口。比如,开发者可以使用 uni.request 方法来发起网络请求,无论是在微信小程序还是 App 中,都能够正常使用。 最后,UniApp 使用各个平台的打包工具将应用打包成可执行文件或可发布的代码文件。对于微信小程序,UniApp 会生成一个可以导入到微信开发者工具中预览和发布的项目文件夹;对于 App,UniApp 会生成原生的 Android 或 iOS 项目,开发者可以进行进一步的编译和发布。 综上所述,UniApp 的运行原理是将开发者编写的代码转换为各个平台的原生代码,并提供跨平台的 API,使得应用能够在不同平台上运行和发布。这种方式减少了开发者的工作量,提高了开发效率,使得开发跨平台应用变得更加简单和便捷。 ### 回答2: UniApp是一种基于Vue.js框架的跨平台开发解决方案,可以同时开发iOS、Android和Web应用。UniApp的运行原理主要是基于两个关键技术点:编译和渲染。 首先,UniApp应用在开发阶段使用Vue.js框架进行编写,开发者使用Vue的语法和相关技术进行业务和界面的构建。UniApp将Vue.js框架进行了扩展和适配,使其能够同时运行在不同的平台上。 在编译阶段,UniApp会将开发者编写的Vue代码转换为原生的JavaScript代码。它会根据应用的配置文件和平台的特性,进行相应的编译优化和转换。通过这个过程,UniApp将统一的Vue代码转换为特定平台的原生代码。 在渲染阶段,UniApp使用了各个平台自带的渲染引擎进行UI的渲染。对于iOS和Android,UniApp使用了各自的原生渲染引擎进行渲染;对于Web平台,UniApp使用了WebView进行渲染。UniApp将编译生成的原生代码交给相应的渲染引擎进行解析和渲染,最终呈现出用户界面。 除了编译和渲染外,UniApp还提供了一套统一的API和组件库。这些API和组件库可以在不同平台上实现一致的功能和样式,开发者可以直接调用这些API和组件进行业务的开发和界面的构建。 综上所述,UniApp的运行原理是通过编译和渲染来实现跨平台的应用开发。通过编译将统一的Vue代码转换为特定平台的原生代码,并使用各个平台的渲染引擎进行UI的渲染,最终实现在不同平台上运行的应用。这种原理使得开发者可以用一套代码同时开发多个平台的应用,提高了开发效率和代码复用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值