纳什恩:JavaScript在Java 8中做得很好

JVM上的JavaScript更好更快,但与重新构建的JavaScript解释器Nashorn的关系并不总是更友好

Nashorn发音为“nass horn”,是德语中“犀牛”的意思这是第二次世界大战中使用的德国坦克驱逐舰的动物名称之一。它也是用Java 8引入的旧的、速度慢的Rhino JavaScript引擎的替代名称。Rhino和Nashorn都是Java虚拟机上运行的JavaScript语言的实现。

强制性声明:JavaScript的名称中可能包含Java,但这两种语言在精神、设计以及实现上都有很大的不同。然而,实现JavaScript解释器的一种方法是将JavaScript编译成Java字节码,Rhino和Nashorn就是这样设计的。

[同样在InfoWorld:我们讨厌Java的15件事|展示你的编程技巧InfoWorld的JavaScript IQ测试.|通过InfoWorld的开发者世界通讯. ]

您可能会从编写Web浏览器脚本的角度来考虑JavaScript,在很大程度上您是正确的。它也用于服务器。例如,Node.js用于构建基于谷歌Chrome的V8 JavaScript引擎的快速、轻量级服务器。Web浏览器中的JavaScript引擎可以访问HTML文档对象模型(DOM),并可以通过DOM操作HTML元素。鉴于不同的Web浏览器有不同的dom和JavaScript引擎,jQuery等框架尝试对程序员隐藏实现细节。

Nashorn和之前的Rhino都明确不支持浏览器DOM。它们是在JVM上实现的,通常在Java应用程序中的最终用户脚本中调用它们。Nashorn和Rhino可以嵌入到Java程序中,并用作命令行shell。当然,从JavaScript编写Java脚本时需要的额外魔法是将两种语言之间的数据和类型不匹配连接起来。

犀牛的问题Rhino的开发始于1997年Netscape的一个倒霉的“Javagator”项目,并于1998年发布到Mozilla.org。然后它被授权给Sun和其他公司。老实说,1998年就像侏罗纪时代一样,互联网的发展——16年后,Rhino已经明显显示出它的年龄。甲骨文公司的吉姆·拉斯基说,纳什恩的主要开发商:

我相信这一切都是真的,但作为一名疲惫的开发人员和开发经理,我觉得最后一句话非常有趣。毕竟,重大重写从来都不是有趣的。从头开始总是有趣的。

目标Nashorn拉斯基对纳什恩的目标描述如下:

  • Nashorn将基于ECMAScript-262 5.1版语言规范,并必须通过ECMAScript-262遵从性测试。
  • 纳什恩将支持javax。脚本(JSR 223) API。
  • 支持从JavaScript调用Java代码和Java调用JavaScript代码。这包括直接映射到javabean。
  • Nashorn将定义一个新的命令行工具jjs,用于在“shebang”脚本、here文档中评估JavaScript代码,并编辑字符串。
  • Nashorn应用程序的性能和内存使用应该比Rhino好得多。
  • 纳颂不会暴露任何额外的安全风险。
  • 提供的库应该在本地化下正确运行。
  • 错误消息和文档将被国际化。

Laskey还明确地用一些“非目标”限制了项目的范围:

  • Nashorn将只支持ECMAScript-262 5.1版。它不支持Edition 6的任何特性,也不支持其他JavaScript实现提供的任何非标准特性。
  • Nashorn将不包含浏览器插件API。
  • Nashorn将不包括对DOM/CSS或任何相关库(如jQuery、Prototype或Dojo)的支持。
  • 纳什恩将不包括直接调试支持。

那么,基于ECMAScript-262 5.1版意味着什么呢?这里的区别在于Rhino是基于较老的、功能较差的Edition 3。javax。脚本(JSR 223) API用于从Java回调到JavaScript。

Nashorn中缺少调试支持是Rhino的一个倒退,Rhino有自己的JavaScript调试器。但是,您可以在至少两个流行的IDE中找到解决这一故意遗漏的方法。

Nashorn命令行工具在阅读了关于jjs的文章后,我很想在我的iMac上试用一下这个shell,但是在安装了Java 8之后,bash shell无法使用它。事实证明,文档和实现并不完全同步。

我知道安装是成功的:

>;java-版本java版本“1.8.0”java(TM)SE运行时环境(构建1.8.0-b132)java热点(TM)64位服务器虚拟机(构建25.0-b70,混合模式)

但是,运行jjs返回-bash:jjs:command-not-found

java /usr/bin/java祝辞

在那里我发现了一个叫做jrunscript的东西,它是jjs的一个变体,可以运行一个额外的启动脚本。这应该让我感到满意,但是我不明白为什么没有将文档化的jjs工具与Java 8运行时的其余部分一起安装在/usr/bin/中。一项小小的研究让我了解了Java 8的JavaVirtualMachines安装。在Mac上,在/Library/Java/JavaVirtualMachines/jdk1.8.0中查找jjs。jdk /内容/ Home / bin /或/图书馆/ Java / JavaVirtualMachines / jdk1.8.0.jdk /内容/ Home / jre / bin /。

如果需要在Mac或Linux上编写脚本,可以在后一个目录中为jjs定义别名,并将其添加到shell配置中。在PC上,可以将正确的jre/bin/目录添加到PATH中。在他的Java8发布视频Jim Laskey建议将jjs复制到/usr/bin/目录,但当我这样做时,我发现jjs无法在运行时正确找到jre。

运行JavaScript脚本为什么要使用两个命令行工具来运行JavaScript脚本?我不是很清楚开发团队是怎么想的,但是jjs有jrunscript没有的功能,而且jrunscript有一个初始化文件。下面是一些使用jjs和jrunscript的简单示例。

美元jrunscript nashorn>警报(“你好,信息世界”);脚本错误:ReferenceError: "alert" is not defined in <STDIN>在第一行

这不起作用,因为alert()是一个浏览器/DOM函数。分析!但我发誓这招在雷诺公司很管用。

nashorn>;print(“你好,信息世界”);你好,信息世界

这是可行的,因为print()是一个核心JavaScript函数。

nashorn>Var a = 1;nashorn>Var b = "1";nashorn>打印(a + b);11 nashorn>打印(+);2 nashorn>辞职(); $

换句话说,我们在这里有一个基本的用于JavaScript的REPL(读取-执行-打印-循环命令行)环境。如果你对a+b的答案感到惊讶,考虑一下:

nashorn>;打印(类型(a+b));字符串

这是JavaScript中松散输入和重载“+”操作符的一个迷人的副作用。根据JavaScript规范,这是正确的行为,而不是一个bug。

Nashorn支持“#”字符作为前导行注释标记,因此jjs和jrunscript可用于用JavaScript编写的可执行“shebang”脚本。在Mac或Linux上,您必须使用chmod实用程序将JavaScript文件标记为可执行文件,以使其可运行。

你会发现jjs中的脚本模式是jrunscript所缺少的。在脚本模式下,反引号内的表达式被传递到外壳进行计算:

$ JJS -scripting jjs>打印(ls);应用程序应用程序(并行)创意云文件桌面…工作

jjs>

脚本模式还支持“heredocs”的扩展,它基本上是Perl和Ruby程序员熟悉的格式的多行字符串。

顺便说一句,Mac键盘上的箭头键在jjs shell中无法正常进行行编辑一个黑客你可以在你的.bashrc或.zshrc文件中创建、安装rlwrap,并将其作为jjs别名的一部分。

从Java调用JavaScript要从Java 8程序中调用Nashorn JavaScript,基本上需要创建一个新的ScriptEngineManager实例,并使用该ScriptEngineManager按名称加载Nashorn脚本引擎。(见这个堆栈溢出问题以简明扼要地总结加载和调试Nashorn。)

最后,您可以向Nashorn引擎传递一个要计算的文件或字符串:

导入javax.script.Invocable;导入javax.script.ScriptEngine;导入javax.script.ScriptEngineManager;导入javax.script.ScriptException。。。尝试{ScriptEngineManager factory=new ScriptEngineManager();ScriptEngine engine=factory.getEngineByName(“nashorn”);engine.eval(“加载”(\“+”src“+”/“+”javascript\u示例“+”/“+”test1.js“+”))catch(例外情况除外){尝试{ScriptEngineManager factory=new ScriptEngineManager();ScriptEngine engine=factory.getEngineByName(“nashorn”);engine.eval(“函数hi”){\nvar a='PROSPER'.toLowerCase();\nmiddle();\nprint('Live long and'+a)}\n函数middle(){\n var b=1;for(var i=0,max=5;i<;max;i++){\nb++;\n}\n print('b is'+b);}hi())}catch(脚本异常示例){nbsp;/nbsp;/…}

注意,脚本总是会生成ScriptException错误,因此需要捕获它们。

从JavaScript调用Java从Nashorn调用Java非常简单,因为Java 8类库内置于Nashorn中:

print(java.lang.System.currentTimeMillis());var file= ;new java.io.file(“sample.js”);print(file.getAbsolutePath());print(file.absolutePath);

注意,默认情况下,Nashorn不导入java包,因为对String或Object的引用与JavaScript中相应的类型冲突。因此,Java字符串就是Java .lang。字符串,而不是字符串。

Nashorn和JavaFX如果您使用-fx开关调用jjs,它将允许您在Nashorn应用程序中使用可视化的JavaFX类。例如,下面的例子从Oracle文档显示一个JavaFX按钮:

var Button = javafx.scene.control.Button;var StackPane = javafx.scene.layout.StackPane;var Scene = javafx.scene.Scene;function start(primaryStage) { primaryStage。title = "Hello World!";,,var button = new button ();,,按钮。text = "Say 'Hello World'";     button.onAction = function() print("Hello World!");     var root = new StackPane();     root.children.add(button);     primaryStage.scene = new Scene(root, 300, 250);     primaryStage.show(); }

调试Nashorn我之前提到过,Nashorn不包含自己的调试器。幸运的是,NetBeans 8和IntelliJ IDEA 13.1都支持调试Nashorn JavaScript。的我之前提到的堆栈溢出问题包括一个有用的NetBeans 8项目,您可以将其用作示例。您会发现,只需在JavaScript文件上使用弹出菜单中的调试项,即可调试Nashorn代码。

在IntelliJ IDEA 13中,您可以使用相同的快捷键(Com/Ctrl-F8)在Java和Nashorn JavaScript文件中设置断点。当您碰到一个JavaScript断点时,您将获得所有常见的调试信息。

Nashorn的设计初衷是为了更好、更快地替代旧的Rhino引擎,从大多数方面来看,它都是成功的。它有一些小缺点,我希望在未来的更新中可以纠正,但目前有一些合理的技巧,可以让您在项目中有效地使用Nashorn。

这篇文章中,“纳什恩:JavaScript在Java 8中做得很好,最初发表于InfoWorld.com。留意本港的最新发展Java编程JavaScript应用技术发展在InfoWorld.com上。了解最新的商业技术新闻,请关注推特上的InfoWorld.com

阅读更多关于应用程序开发的内容在InfoWorld的应用开发频道。

这个故事,“纳什恩:JavaScript在Java 8中变得伟大”最初是由信息世界

加入网络世界社区足球竞猜app软件脸谱网LinkedIn评论最重要的话题。

版权©2014足球竞彩网下载

工资调查:结果在