繁体   English   中英

Javascript - 编译语言?

[英]Javascript - Compiled language?

本人初学Web开发,正在研究JavaScript。

来自斯坦福大学的课程

JavaScript 是解释型语言,不是编译型语言。 C++ 或 Java 等程序在运行前需要编译。 源代码通过称为编译器的程序传递,将其翻译成机器可以理解并可以执行的字节码。 相比之下,JavaScript 没有编译步骤。 相反,浏览器中的解释器读取 JavaScript 代码,解释每一行并运行它。 更现代的浏览器使用一种称为即时 (JIT) 编译的技术,它会在 JavaScript 即将运行时将其编译为可执行字节码。

来自You Don't Know JS:Scope 和Kyle Simpson的闭包:

... 但尽管 JavaScript 属于“动态”或“解释”语言的一般类别,但它实际上是一种编译语言。

为了简单起见,我们只是说 JavaScript 的任何片段都必须在它被执行之前(通常就在之前)被编译,所以; JS 编译器会把程序 var a = 2,先编译它,然后准备执行它。 通常马上。

从 Stack Overflow 的一些问题中,有一些想法,例如:它取决于语言的实际实现。

你有什么想法?

Chrome 浏览器使用 V8 引擎编译 Javascript 就像其他浏览器可能使用 Rhino 或 SpiderMonkey 一样。

V8 是谷歌在 C++ 中构建的 JavaScript 引擎。它用于在客户端(Google Chrome)和服务器端(node.js)应用程序中编译 JS。 为了获得速度,V8 将 JavaScript 代码翻译成更高效的机器代码,而不是使用解释器。

V8 通过实现 JIT(即时)编译器在脚本执行时将 JavaScript 代码编译为机器代码,就像许多现代 JavaScript 引擎(例如 SpiderMonkey 或 Rhino (Mozilla))正在做的那样。 与 V8 的主要区别在于它不生成字节码或任何中间代码。 它只是即时编译 JavaScript。

希望这可以帮助!

好吧,您可能会了解语义和术语差异,但有两点很重要:

  • Javascript(在 web 页面中)以其源代码形式(或至少以最小化的文本形式)分发,而不是作为提前编译的二进制文件

  • Javascript 甚至没有被浏览器编译成可执行的机器代码(尽管现在其中的某些部分可能作为性能优化),而是通过虚拟机执行

在此上下文中使用的术语“已编译”指的是一种语言,通常假定它被直接翻译成将要运行的机器的本地语言或格式。 典型案例包括 C 和 C++。但是,请理解这两种语言也是可以解释的。 C 解释器的一个例子是 Pico C,它处理 C 的一个子集。

所以,真正的问题是关于环境。 一种语言可以在编译或解释环境中运行。 通过以下测试可以明确区分这两种情况:

    Does the language possess a "command level" mode
    in which forward references are inherently impossible?

对此稍加思考。 解释性语言实时读取其规范。 前向引用是指在制定规范时不存在的事物。 由于机器(还)没有被赋予预知或时间旅行的便利(即“时间循环逻辑”),因此这些引用本质上是无法解析的。

如果这样的级别被定义为语言的强制性部分,则可以说该语言是解释性的; 否则,它可以说是编译的。 BASIC 被解释,因为它的一些命令直接引用该层(例如“列表”命令)。 类似地,高级 AI 语言 Prolog,按照这个标准,是一种解释性语言,因为它也拥有直接引用这一层的命令。 例如,“?-”命令本身就是一个实际的提示符; 但它的数据库命令也引用并维护了命令级层的当前state。

然而,这并不排除解释语言的某些部分受制于编译或编译器使用的方法,或编译语言在命令模式级别运行。 实际上,这就是像 C 或 C++ 这样的语言的调试器已经是这样的,只是举个例子。

.大多数被定义为具有命令级层的语言,通常必须编译成 that at least parts of it compile into something:特别是,如果语言满足以下条件,那么至少将其部分编译成某种东西:

    Does the language possess a facility for user-defined codelets,
    for instance: subroutines, functions, lambdas, etc.?

原因很简单:你打算把代码放在哪里,在定义之后再使用,以什么格式? 逐字保存和运行它的效率极低,因此通常会将其翻译成另一种形式,即:(a) 语言内部的范式(在这种情况下,语言的 rest 可被视为“语法糖“对于正常 forms 所在的缩减子集语言),(b)转换为语言外部规范形式(即“字节码”),或(c)两者的组合 - 它可能首先进行语言内部规范化, 在将其翻译成字节码之前。

因此,大多数“解释型”语言都被编译成某种东西。 唯一真正的问题是:(1)它们被编译成什么,以及(2)它被编译成的代码何时/如何运行——这与上述“命令级”模式的问题有关。

如果小码被编译成与目标无关的形式——这是通常在谈到“字节代码”时所指的形式——那么它就不是该术语通常所指的意义上的“编译”。 术语编译通常是指翻译成运行该语言的机器的本地语言。 在那种情况下,翻译器的数量与语言可能运行的机器类型一样多——翻译器本质上是依赖于机器的。

这两种情况并不相互排斥。 因此,字节码翻译器可能会作为本地代码编译的一个阶段出现,解释语言的小码被翻译并直接存储在运行该语言的机器的本地语言中。 这就是所谓的“及时”编译(或 JIT)。

区别有点模糊。 即使是编译语言,如 C 或 C++,也可能在具有已编译甚至预编译小码的系统上运行,这些小码在程序运行时加载。

我对 JS 的了解还不够多,无法对它发表任何明确的看法——除了可以从观察中推断出来的内容。

首先,由于 JS 代码存储为小码,并且通常在需要使用的基础上在 web 客户端中运行,因此 的实现很可能会将小码编译(或预编译)为中间字节码形式。

into the native code of the machine it is running on, since this may compromise the security of the machine by providing leaks through which malicious code can be sneaked into and through.其次,出于安全原因,它不太可能编译到运行它的机器的本机代码中,因为这可能会提供漏洞,恶意代码可以通过这些漏洞潜入并通过,从而危及机器的安全性。 这就是浏览器应该遵守的“沙盒”功能。

normally used directly by a person on the other end as a language like Basic or even Prolog is used.第三,它通常被另一端的人直接使用,因为使用像 Basic 甚至 Prolog 这样的语言。 但是,在许多(甚至大多数)实现中,它确实具有“调试”模式。 例如,浏览器甚至可以允许普通用户查看和编辑/调试 JS 代码。 尽管如此,除了出现在 web 浏览器本身中的内容之外,实际上并没有命令层本身。 这里没有解决的问题是浏览器是否允许在 JS 代码中进行前向引用。 如果是这样,那么它就不是真正的命令级环境。 但它可能取决于浏览器。 例如,它可能会在启动任何 JS 代码之前加载整个 web 页面,而不是在加载页面时尝试实时运行 JS,在这种情况下,前向引用是可能的。

第四,如果该语言想要在执行速度方面高效,它将具有某种形式的 JIT——但这将需要对 JS 编译器本身进行严格验证,以确保没有任何东西可以通过 JIT 从“沙箱”中溜出进入主机上的禁止代码。

我很确定那里有 JS 编辑器/解释器,只是为了有一种开发 JS 的方法。 但我不知道对命令层的任何引用是否是 JS 规范的强制性部分。 如果存在这样的规范,那么我们可以称其为真正的解释语言。 否则,它跨越了两种语言类型之间的边界线,作为一种旨在像解释语言一样实时运行的语言,但它允许直接编译为运行它的机器的本机代码。

translate an old stand-by text-based game (lunar lander) directly from the (interpreted) language FOCAL into C-BC (a C-like extension to POSIX BC whose source is located on GitHub here https://github.com/RockBrentwood/CBC ).对我来说,最近当我试图将一个旧的基于文本的备用游戏(月球着陆器)直接从(解释的)语言 FOCAL翻译成 C-BC(POSIX 的类 C 扩展)时,这个问题变得很重要BC 的来源位于 GitHub 此处https://github.com/RockBrentwood/CBC )。 C-BC 与 POSIX BC 一样,被解释但允许用户定义小码,因此 BC 的实现通常将“字节码”语言定义为 go(历史上:这是“dc”)。

FOCAL 语言有一种运行时语言 - 理论上可以编译,但也有一个命令层子集(例如“库”或“擦除”命令),它不允许尚未定义的前向引用,尽管运行时语言允许前向引用。

与 GNU-BC 不同,C-BC 有 goto 语句和标签,因此可以直接翻译游戏。 然而,在命令级别(在 BC 文件中是文件范围的顶层),这是不可能的,因为文件代码的顶层是 - 就 BC 解释器而言 - 参考可能还不存在的东西,因为程序也可以由用户实时输入。 相反,整个源代码必须包含在 {... } 括号中——在执行之前首先将其完整地编译为字节码。 所以,这是一个用户定义的小码的例子,也是为什么大多数解释语言必须有一些工具来编译成某些东西的教科书例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM