为什么 Java 代码需要编译而 JavaScript 代码不需要

18

为什么用Java编写的代码需要编译成字节码才能被JVM解释,而用JavaScript等语言编写的代码不需要编译就可以直接在浏览器中运行呢?

有没有简单易懂的方式来理解这个问题呢?

这两种语言之间的根本差别是什么,可能有助于理解这种行为?

我不是计算机科学专业的学生,所以请原谅我的幼稚问题。


4
JavaScript 是由浏览器解释的,而不是像 C 和汇编语言那样由计算机的实际硬件解释。 - thatidiotguy
2
@thatidiotguy 什么意思。如今JavaScript很少被解释了(Chrome的V8甚至没有*解释器),"C汇编"根本没有任何意义,汇编代码根本没有被执行,它只是简单地转换成机器码。虽然我必须要给你赞许,因为你认识到最终机器码也只是解释而已。 - user395760
1
可能是编译语言与解释语言的重复问题。 - jbabey
4个回答

25

在历史上,JavaScript 是一种解释型语言。这意味着解释器接受源代码并一步执行全部内容。这种方式的优点是简单和灵活,但解释器非常慢。编译器将高级语言转换为低级语言,然后本地处理器或虚拟机(在这种情况下是 Java VM)可以直接执行。这样做会更快。

现代浏览器中的 JavaScript 现在是即时编译的。因此,当脚本加载时,JavaScript 引擎首先将其编译成字节码,然后执行它。从最终用户的角度来看,整个编译过程被省略了,因为浏览器开发人员(幸运的是)坚持要求 JavaScript 不需要显式编译。

Java 一开始就是一种始终具有显式编译步骤的语言。但在许多情况下,这已经不再正确了。像 IntelliJ 或 Eclipse 这样的 IDE 可以即时编译 Java,并在许多情况下省去显式编译步骤。


是的!现在我可以看到Java IDE中只有运行按钮。 - Ganesh Chowdhary Sadanala
还想指出现代Web浏览器正在回归解释器。它们采用混合方法,开始时进行解释,然后切换到编译。这使JavaScript能够更快地启动和运行。 - Matt Greer

3
JavaScript和Java不是同一件事。虽然它们可能有相似的名称,但我建议您参考JS大师 - Douglas Crockford来澄清它们实际上根本没有关系。
事实上,没有什么可以阻止Java成为一种解释性语言,同样也没有什么可以阻止JavaScript成为一种编译语言(Chrome的JavaScript引擎确实进行了编译以提高速度,并且做得非常好)。
在浏览器的上下文中,Java与Flash或Silverlight一样运行-需要插件并且浏览器作为该插件的主机;其中托管了一个Java运行时环境。
Javascript旨在成为浏览器的脚本语言,这就是为什么浏览器可以本地理解它的原因。浏览器如何实际执行代码,完全取决于浏览器。也就是说-它可以纯粹在脚本级别上运行,假设对下一行代码一无所知,并运行纯软件堆栈;或者它可以执行一些JIT,将代码更接近硬件,并(希望)提高速度。

2
任何语言都可以编译和解释。在两种情况下,一段软件必须读取源代码,拆分它,解析它等等以检查某些要求,然后为程序的每个部分分配含义。唯一的区别是编译器随后会生成具有(几乎)相同含义的代码,使用另一种语言(JVM字节码、JavaScript、机器码或其他内容),而解释器则立即执行程序的含义。
现实中,情况既简单又复杂。在许多语言中,其中一种更适合这两种方法之一 - Java是静态类型的,程序的含义相对较少动态,因此您可以编译它并因此执行一些需要在运行时完成的工作。JavaScript是动态类型的,您无法在运行时决定很多事情(例如+是加法还是连接),因此编译不会为您提供太多性能。然而,在动态语言实现中,混合使用编译器和解释器(编译到简化的中间表示,然后进行解释和/或编译)越来越受欢迎。还有一个事实是,现代JavaScript实现确实进行了编译,事实上V8从来没有解释过任何东西。

0
由于Java和Javascript之间编译层的复杂性,Javascript存在一些限制。由于字节码在为特定操作系统和硬件编写的JVM平台上执行,字节码执行具有更多访问系统资源的优势。即使C代码也可以嵌入到Java字节码中。另一方面,由于Javascript只在浏览器上运行,因此它能做的事情比较少。
Java平台有两个主要部分:Java编程语言和JVM。这使得每个部分只关注自己的领域。这就是为什么JVM不处理Java编程语法的原因。这类似于运行C代码时,链接不会处理C代码而是汇编代码。
JVM平台中的字节码类似于C中的汇编代码。
最终,所有表示都被转换为二进制表示,然后以某种方式成为电信号。这证明我们需要编程级别。

C代码不能嵌入JVM代码中。虽然可能可以,但不会被执行。CLR确实允许“不安全”的代码,但那是完全不同的事情。此外,关于JS和外部世界,请参见V8、node.js和common.js。 - user395760
我是指使用JNI。您可以调用对象文件(dll、so)中的任何方法。 - Ahmet Karakaya
好的,没错(虽然我不会称之为“在Java字节码中嵌入”)。但是你也可以通过任何JavaScript引擎公开本机代码。 - user395760
实际上,正如您所知道的,Java平台有两个主要部分。Java编程语言和JVM。它使每个部分只关注自己的领域。这就是为什么JVM不处理Java编程语法的原因。这类似于运行C代码时链接器不处理C代码而是汇编代码。 - Ahmet Karakaya
我知道这个,但我不知道这与什么相关。 - user395760

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接