重要提示:
您似乎提倡剥离的、静态类型的可编译 JS 版本。首先表明您对 JS 是什么一无所知:一种多范式编程语言,支持基于原型的 OO、命令式和函数式编程范式。关键是功能范式。除了在定义自己的中缀运算符后可以进行强类型化的 Haskell 之外,函数式语言不能是静态类型的 AFAIK。想象一下返回闭包的类 C 函数定义:
function a = (function (Object g)
{
char[] closureChar = g.location.href;
Object foo = {};
Function foo.bar = char* function()
{//This is a right mess
return &closureChar;
};
}(this));
函数也是第一类对象。使用大量返回对象的 lamda 函数、可能返回自身的引用函数、其他函数、对象或原语......你到底要如何编写所有这些?Js 函数是一种创建范围、构建代码、控制程序流程的方式,因为它们是您分配给变量的东西。
提前编译 JS 的问题很简单:你编译的代码必须在如此多的不同平台上运行:运行 Windows、OSX、linux、UNIX 的台式机/笔记本电脑以及平板电脑和智能手机移动浏览器...
即使您确实设法编写和编译运行在所有平台上的 JS,JS 的速度仍然受限于它是单线程的,并且运行在 JS 引擎上(就像 Java 在 VM 上运行)。
编译代码客户端已经完成。诚然,这需要一些时间,但不是很多。这是相当资源密集型的,因此大多数现代浏览器都会以已经完成大量预处理的方式缓存代码。总是可以编译的东西,也将被缓存在它们的编译状态中。V8 是一个开源的、快速的 JS 引擎。如果需要,您可以查看源代码,了解如何确定 JS 代码的哪些方面已编译,哪些未编译。
即便如此,这只是 V8 的工作方式...... JS 引擎与代码运行的速度有更多关系:有些非常快,有些则不然。有些人在一件事上速度更快,而另一些人在另一个领域的表现优于所有竞争对手。更多细节可以在这里阅读
剥离 DOM 部分并没有从语言中剥离任何东西。DOM API不是 JS 本身的一部分。JS 是一种表达能力很强,但在核心,小型语言,就像 C 一样。两者都没有留给自己的设备的 IO 能力,也无法解析 DOM。为此,JS 的浏览器实现可以访问 DOMParser 对象。
您建议使用最小的 DOM ......嘿,任何人都支持改进的 DOM API。这远非网络上最好的东西。但是你必须意识到 DOM 和 JS 是独立的实体。DOM(和 DOM API)由 W3 管理,而 ECMA 负责 JS。彼此都没有任何关系。这就是为什么 DOM 不能从 JS 中“剥离”出来的原因:它从一开始就不是它的一部分。
由于您将 JS 与 C++ 进行比较:您可以编写可以在 Windows 和 Linux 机器上编译的 C++ 代码,但这并不像听起来那么容易。但是由于您自己参考了 C++,我想您也可能知道这一点。
说到这一点,如果您看到 C++ 和 JS 之间唯一真正的区别是静态类型与动态类型,那么您真的应该花更多时间学习 JS。
虽然它的语法类似于 C,但语言本身与 Lisp 有更多的相似之处(即函数式编程)。它不知道类本身,但使用原型……说实话,动态类型真的没什么大不了的。
所以,底线:
编译 JS 以在每台机器上运行将导致类似于 MS 的 .NET 框架的东西。其背后的理念是:“一次编写,到处运行” ……事实证明这根本不是真的。
Java是X 平台的,但这仅仅是因为它没有编译为本机代码,而是在虚拟机上运行。
最后,ECMAScript 标准(JS 是其最常见的实现)并不是那么好,它是该领域所有大型竞争对手共同努力的结果:Mozilla、谷歌、微软和一些无关紧要的瑞士公司。这是一个巨大的妥协。想象一下这三个大牌同意一起为 JS 做一个编译器。微软将推出其JScript 编译器作为最好的,Google 将有自己的想法,而 Mozilla 可能会准备好 3 种不同的编译器,具体取决于社区的需求。
编辑:
您进行了编辑,澄清您在谈论客户端 JS。因为您觉得有必要指定这一点,所以我觉得您似乎并不完全确定 JS 在哪里结束,以及浏览器在哪里接管。
JS 被设计成一种非常可移植的语言:它没有 IO 功能,支持多种开发范式,并且(最初)是一种完全解释性的语言。诚然,它是在考虑 Web 的情况下开发的,但是您可以并且有些人确实可以使用这种语言来查询数据库 (MongoDB),作为替代的批处理脚本语言 (JScript) 或服务器端脚本语言 (backbone, node.js,...)。有些人使用 ECMAScript(JS 的基本标准)来制作自己的编程语言(是的,我说的是 Flash ActionScript)。
根据用例,JS 将被授予访问非语言原生对象/API 的权限(document
, [Object http].createServer
,[Object file].readFileSync
分别用于 DOM 访问、Web 服务器功能和 IO)。这些往往构成瓶颈,而不是语言本身。
正如我所暗示的,JS最初是一种解释性语言。就像现在一样,编译语言和解释语言之间的分界线在过去十年中一直在消退,老实说。
C/C++ 曾经是严格编译的语言,但在某些情况下(.NET)C++ 代码不再需要编译为机器代码......
同时,像 Python 这样的脚本语言被用于很多目的,它们'通常被视为一种编程语言,因为脚本语言一词在某种程度上暗示了一种“次要语言”。
几年前,随着 PHP5 的发布,ZendEngine2 也发布了。从那时起,PHP 被编译为字节码并在虚拟机上运行。您可以使用 APC 缓存字节码。bcompiler 允许您从 PHP 代码生成独立的可执行文件,就像 Facebook 的 HPHPc(已弃用)用于将 PHP 编译为 C++,然后编译为本机代码一样。现在,facebook 使用 HHVM,这是一个自定义虚拟机。在这里了解更多信息。
在 JavaScript 解释器(现在称为引擎)中可以看到同样的演变。它们不是你每天解析和执行的旧线程,你似乎仍然认为它们是。在内存管理、JITCompilation(甚至尾栈优化)、优化以及你有什么方面,有很多魔法正在发生……
所有伟大的事情,但这些使得很难确定实际的瓶颈在哪里。每个引擎优化的方式比IE6与IE10的差异还要大,因此几乎不可能确定瓶颈。如果一个浏览器需要 10 秒来完成一项 DOM 密集型任务,那么另一个浏览器可能只需要 1~2 秒。但是,如果相同的浏览器相互竞争以检查 RegExp 对象的性能,则启动可能会在另一只脚上。
我们不要忘记,在您撰写有关您的发现的博客文章之后,您必须检查是否没有任何浏览器发布了声称可以加快某些任务的新版本/更新。