有时候写web应用程序的代码感觉很神奇,因为我们只是写了一系列的字符,然后在浏览器中看到效果。但是了解魔术背后的技术可以帮助您更好地提高编程技能。至少当你试图解释JavaScript支持的网络或移动应用程序的幕后发生的事情时,你会觉得自己不那么白痴了。很多年前,当我还是一名研究生讲师时,我向一位教授抱怨说我没有掌握那些特别难的法语语法点来教我的本科生。我记得她当时说过的话:“有时候,学习的唯一途径就是教它。”试图向工程师解释NativeScript如何通过JavaScript引擎在幕后工作,在运行时连接到原生API——面对这种复杂的工作很容易迷失在一片杂草丛中。事实上,任何JavaScript开发人员都应该对我们日常使用的技术背后的引擎感到好奇。现在让我们仔细看看JavaScript引擎的作用,为什么不同的平台使用不同的引擎,这些年来它们是如何发展的,以及为什么我们作为开发人员应该关心。首先,一些专业术语“JavaScript引擎”通常被称为虚拟机的一种。“虚拟机”是指给定计算机系统的软件驱动仿真器。虚拟机有很多种,根据它们模拟或替代真实物理机的程度来分??类。例如,“系统虚拟机”提供了一个完整的仿真平台,操作系统可以在该平台上运行。Mac用户很熟悉Parallels作为虚拟机,它允许您在Mac上运行Windows系统。另一方面,“进程虚拟机”并不具备运行程序或进程的所有功能。Wine是一个进程虚拟机,允许您在Linux机器上运行Windows应用程序,但不在Linux中提供完整的Windows操作系统。JavaScript虚拟机是一种进程虚拟机,专门设计用于解释和执行JavaScript代码。注意:区分在浏览器中布置页面的布局引擎和解释和执行代码的底层JavaScript引擎很重要。一个很好的解释可以在这里找到。那么,究竟什么是JavaScript引擎以及它的作用是什么?JavaScript引擎的基本工作是将开发人员编写的JavaScript代码转换为高效、优化的代码,可以被浏览器解释甚至嵌入到应用程序中。事实上,JavaScriptCore称自己为“优化虚拟机”。更准确地说,每个JavaScript引擎都实现了一个ECMAScript版本,JavaScript是它的一个分支。随着ECMAScript的不断发展,JavaScript引擎也在不断发展。之所以有这么多不同的引擎,是因为它们中的每一个都被设计为在不同的网络浏览器、无头浏览器或像Node.js这样的运行时中运行。您可能熟悉Web浏览器,但什么是无头浏览器?它是一个没有图形用户界面的网络浏览器。它们在对Web产品进行自动化测试时很有用。一个很好的例子是PhantomJS。那么Node.js与JavaScript引擎有什么关系呢?Node.js是一个异步的、事件驱动的框架,可让您在服务器端使用JavaScript。由于它们是驱动JavaScript的工具,因此它们也由JavaScript引擎提供支持。根据上面虚拟机的定义,很容易理解JavaScript引擎被称为进程虚拟机,因为它的唯一目的就是读取和编译JavaScript代码。这并不意味着它只是一个简单的引擎。例如,JavaScriptCore有六个“构建块”,用于分析、解释、优化和垃圾收集JavaScript代码。它是如何工作的?当然,这取决于发动机。引起我们注意的两个主要引擎都利用了NativeScript、WebKit的JavaScriptCore和Google的V8引擎。这两个引擎处理代码的方式不同。JavaScriptCore执行一系列步骤来解释和优化脚本:它执行词法分析,即将源代码分解为一系列具有明确定义含义的符号或字符串。这些符号然后由解析器分析以构建语法树。然后四个JIT(Just-In-Time)进程开始参与,分析并执行解析器生成的字节码。什么?简单来说,JavaScript引擎加载你的源代码,将其分解为字符串(也称为分词),将这些字符串转换为编译器可以理解的字节码,然后执行这些字节码。谷歌的V8引擎,用C++编写,也编译和执行JavaScript源代码,处理内存分配和垃圾收集。它被设计成由两个可以将源代码直接编译成机器代码的编译器组成:Full-codegen:一个快速的编译器,输出未优化的代码Crankshaft:一个慢速的编译器,如果Crankshaft确定了需要的代码待优化的是Full-codegen生成的未优化代码,它将替代Full-codegen。这个过程称为“曲轴转动”。一旦在编译过程中生成了机器代码,引擎就会向浏览器公开ECMA标准中指定的所有数据类型、运算符、对象、函数,或任何需要在运行时使用的内容。NativeScript就是这种情况。有哪些JavaScript引擎?有许多令人眼花缭乱的JavaScript引擎可用于解释、分析和执行客户端代码。随着每个浏览器版本的发布,其JavaScript引擎可能会发生变化或优化,以跟上JavaScript代码执行技术状态的变化。在您完全被这些浏览器引擎的名称搞糊涂之前,请记住这些引擎和基于它们的浏览器中包含许多营销元素。在这篇对JavaScript编译的有用分析中,作者讽刺地指出:“你不知道的是,大约37%的编译器是由营销组成的,重塑编译器的品牌是你能做的。”为数不多的事情之一,智能营销,因此有了一系列名称:SquirrelFish、Nitro、SFX……”。在牢记营销对命名和重命名这些引擎的影响的同时,注意一些重要事件是很有用的JavaScript引擎发展史。我做了一个简单易懂的图表给你:Browser,HeadlessBrowser,orRuntimeJavaScriptEngineMozillaSpidermonkeyChromeV8SafariJavaScriptCoreIEandEdgeChakraPhantomJSJavaScriptCoreHTMLUnitRhinoTrifleJSV8Node.jsV8Io.js*V8*JavaScriptCore重写为SquirrelFish,升级版为QuirrelFishExtreme,也称为Nitro,但构成Webkit实现基础的JavaScript引擎是JavaScriptCore(如Safari)。**iOS开发者要注意移动设备上的Safari使用Nitro,但是UIWebView不包含JIT编译,所以体验会比较慢。不过,开发者可以在iOS8中将WKWebView与Nitro结合使用,体验明显更快。混合移动应用程序的开发人员应该可以松一口气了。*io.js最终从Node.js中分离出来的原因之一是为了支持V8版本的引擎。如此处所述,这仍然是一个挑战。我们为什么要关心?JavaScript引擎的代码解析和执行过程的目标是在尽可能短的时间内编译出优化的代码。最重要的是,这些引擎的发展与我们对发展网络和移动平台的持续追求密切相关,使它们尽可能地高性能。要跟踪这种演变,您可以在基准图中查看各种引擎的行为,正如arewefastyet.com所总结的那样。例如,比较Chrome在V8引擎和非曲轴引擎下的性能是很有趣的。任何Web开发人员都应该意识到,我们努力编写、调试和维护的代码在不同的浏览器中必然会有不同的表现。为什么某段代码在一个浏览器上运行缓慢,但在另一个浏览器上运行得更快?同样,移动开发人员,尤其是使用webview显示页面内容的混合移动应用程序开发人员,或使用NativeScript等运行时环境的开发人员,想知道什么引擎正在解释和执行他们的JavaScript代码。移动网络开发人员应该了解浏览器在这些微型设备上的局限性和可能性。作为想要不断成长的网络、移动或应用程序开发人员,掌握JavaScript引擎的变化可以带来巨大的回报。
