【问题标题】:Why does Java code need to be compiled but JavaScript code does not为什么Java代码需要编译而JavaScript代码不需要
【发布时间】:2012-08-04 21:47:45
【问题描述】:

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

有没有简单的方法来理解这个?

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

我不是CS学生,所以请原谅这个问题的幼稚。

【问题讨论】:

  • Javascript 由浏览器解释,而不是由计算机的实际硬件(如 C 程序集)解释。
  • @thatidiotguy 笏。 JavaScript 现在很少被解释(Chrome 声名鹊起的 V8 甚至没有解释器),“C 汇编”根本没有任何意义,而且汇编代码根本不执行,它是只是简单地变成机器代码。虽然我必须给你一些道具来实现机器代码也只是在一天结束时被解释。

标签: java javascript compilation bytecode


【解决方案1】:

由于Java 和Javascript 之间的编译层次复杂,Javascript 存在一些限制。由于字节码是在为特定操作系统编写的 JVM 平台上执行的,而硬件字节码执行在访问系统资源方面更有优势。甚至 C 代码也可以嵌入到 Java 字节码中。另一方面,由于 Javascript 仅在浏览器上运行,因此与它的关系较少。

Java 平台有两个主要部分。 Java 编程语言和 JVM。它使每个部分只关注自己的领域。这就是 JVM 不处理 Java 编程语法的原因。类似于运行C代码时链接不处理C代码而是汇编。

JVM 平台中的字节码很可能是 C 中的程序集。

最终所有的表示都被转换为二进制表示,然后以某种方式转换为电信号。它证明我们需要编程水平。

【讨论】:

  • C 代码不能嵌入到 JVM 代码中。好吧,它可能可以但不会执行。 CLR 确实允许unsafe 代码,但那是完全不同的事情。另外,关于 JS 和外部世界,请参阅 V8、node.js 和 common.js。
  • 我的意思是使用 JNI。可以调用目标文件(dll、so)中的任何方法
  • 好吧,那是真的(不过我不会称其为“嵌入 java 字节码”)。但您也可以通过任何 JavaScript 引擎公开本机代码。
  • 其实你可能知道Java平台有两个主要部分。 Java 编程语言和 JVM。它使每个部分只关注自己的领域。这就是 JVM 不处理 Java 编程语法的原因。类似于运行C代码时链接不处理C代码而是汇编。
  • 我知道,但我不知道这有什么关系。
【解决方案2】:

任何语言都可以编译和解释。在这两种情况下,软件都必须读取源代码、拆分、解析等,以检查某些需求,然后为程序的每个部分赋予含义。唯一的区别是编译器随后会继续生成具有(几乎)相同含义的另一种语言(JVM 字节码、JavaScript、机器代码或完全不同的东西)的代码,而解释器会立即执行程序的含义。

现在,在实践中它既简单又复杂。它在许多语言中更简单,更适合这两种语言中的一种——Java 是静态类型的,程序含义的动态性相对较小,因此您可以编译它,从而完成一些原本需要在运行。 JavaScript 是动态类型的,在运行时之前您无法决定很多事情(例如 + 是加法还是连接),因此编译不会为您提供太多性能。然而,编译器和解释器的混合(编译为简化的中间表示,然后解释和/或编译)在动态语言实现中越来越流行。还有一个事实是,现代 JavaScript 实现确实编译,而事实上 V8 从不解释任何东西。

【讨论】:

    【解决方案3】:

    JavaScript 和 Java 不是一回事。他们可能有一个相似的名字,但我建议您参考JS guru - Douglas Crockford 以帮助澄清他们实际上根本不相关的事实。

    现实情况是,没有什么能阻止 Java 成为一种解释型语言,同样也没有什么能阻止 JavaScript 成为一种编译型语言(Chrome 的 javascript 引擎确实会进行编译以提高速度,并且做得非常好)。

    在浏览器的上下文中,Java 的运行方式与 Flash 或 Silverlight 相同——需要一个插件,并且浏览器充当该插件的宿主;它承载了一个 Java 运行时环境。

    Javascript 被设计为浏览器的脚本语言,这就是浏览器可以原生理解它的原因。 浏览器如何真正实现代码的运行,然而,完全取决于浏览器。也就是说 - 它可以纯粹在脚本级别运行,假设对下一行代码的了解为零并运行纯粹的基于软件的堆栈;或者它可以执行一些 JIT 以使代码更接近硬件并(希望)提高速度。

    【讨论】:

      【解决方案4】:

      从历史上看,JavaScript 是一种解释型语言。这意味着解释器接受源代码并一步执行。这里的优点是简单和灵活,但是解释器很慢。编译器将高级语言转换为本地处理器或 VM(在本例中为 Java VM)可以直接执行的低级语言。这要快得多。

      现代浏览器中的 JavaScript 现在是动态编译的。所以当脚本被加载时,JavaScript 引擎做的第一件事就是把它编译成字节码然后执行。从最终用户的角度来看,缺少整个编译步骤的原因是浏览器开发人员(谢天谢地)维护了 JavaScript 没有显式编译的要求。

      Java 从一开始就是一种始终具有显式编译步骤的语言。但在许多情况下,这不再是真的了。像 IntelliJ 或 Eclipse 这样的 IDE 可以即时编译 Java,并且在许多情况下删除了显式编译步骤。

      【讨论】:

      • 是的!现在我只能在 ide 的 java 中看到运行按钮
      • 还想指出,现代网络浏览器正在回归解释器。他们正在采用一种混合方法,从开始解释,然后转向编译。这使 JavaScript 能够更快地启动和运行。
      猜你喜欢
      • 2012-04-24
      • 2017-10-07
      • 1970-01-01
      • 2018-12-12
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多