Java 8 Nashorn 教程

图片 4

图片 1

函数语法

万三只是简短的一行函数大家能够不用大括号:

function sqr(x) x * x;
print(sqr(3));    // 9

在动用JavaScript原生类型调用Java方法时,Nashorn
如哪个地方理类型调换?让大家通过轻巧的例证来弄掌握。

超过半数品种是莫衷一是的,其复杂度和供给引致了汪洋的内部原因,你该怎么出手代码库呢。固然如此,在全数地点都有一致性的靶子,那便是代码品质

属性绑定

发源分歧对象的质量能够绑定在一块儿:

var o1 = {};
var o2 = { foo: 'bar'};

Object.bindProperties(o1, o2);

print(o1.foo);    // bar
o1.foo = 'BAM';
print(o2.foo);    // BAM
function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; this.getFullName = function() { return this.firstName + " " + this.lastName; }}

静态代码剖析

Java Beans

大家无需健康的用 getter 恐怕 setter
来访谈类成员属性,可直接用属性名简单访谈 Java Bean 中的属性。比如:

var Date = Java.type('java.util.Date');
var date = new Date();
date.year += 1900;
print(date.year);  // 2014

JavaScript方法getFullName能够因而callMember()ScriptObjectMirror上调用。

激活 JavaScript REPL 的一种途径是张开浏览器的调控台,它产生了对
JavaScript 代码求值的分界面。

使用Nashorn

Nashorn javascript
引擎要么在java程序中以编制程序的办法利用依旧在指令行工具jjs使用,jjs在目录$JAVA_HOME/bin中。即便您筹算构建一个jjs的号子链接,如下:

$ cd /usr/bin
$ ln -s $JAVA_HOME/bin/jjs jjs
$ jjs
jjs> print('Hello World');

本学科关心的是在java代码中采纳 nashorn
,所以咱们以往跳过jjs。用java代码来三个轻巧易行的  HelloWorld示例,如下:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello World!');");

为了在java中举办JavaScript代码,首先利用原来Rhino (旧版Java中来自Mozilla的蒸内燃机卡塔尔国中的包javax.script来创设三个nashorn脚本引擎。.

不仅可以够向地点那样把JavaScript代码作为叁个字符串来直接实践,也可放入贰个js脚本文件中,如:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("script.js"));

Nashorn javascript是基于 ECMAScript
5.1 ,但nashorn后续版本将支撑 ECMAScript 6:

脚下Nashorn的战略是遵从ECMAScript标准。 当我们发表JDK
8时,大家将促成ECMAScript
5.1正式。后续的 Nashorn的版本将实现 ECMAScript Edition
6标准。

Nashorn定义了重重语言和强盛了 ECMAScript规范的API
。接下来大家看看java与JavaScript的通讯。

数组调换

一些像样java.util的包能够不利用java.typeJavaImporter一贯访谈:

var list = new java.util.ArrayList();list.add;list.add;list.add;

上边包车型大巴代码将Java列表转变为JavaScript原生数组:

var jsArray = Java.from;print; // s1,s2,s3print(Object.prototype.toString.call; // [object Array]

上面包车型大巴代码施行相反操作:

var javaArray = Java.to([3, 5, 7, 11], "int[]");

小心,JavaScript
里的指标是任何事物的照耀,对象的每特本性(attribute)都在同多个映射里:函数、属性(property)、构造器;易变性带给了更加大的祸患,而对于
Java,你起码可以确定保障艺术和字段构造在某种程度上是平静的。

在接下去的差不离15秒钟里,您将学习怎么在 JVM 上动态运转 JavaScript。
通过有个别精短的代码示例演示目前 纳什orn 的言语特色。 学习 Java 与
JavaScript 的相互作用调用。最终包罗什么在平常的 Java 业务中结成动态脚本。

var MyJavaClass = Java.type('my.package.MyJavaClass');var result = MyJavaClass.fun1('John Doe');print;// Hi there from Java, John Doe// greetings from java

我们只是看看了 JavaScript 的冰山一角,并尽可能介绍部分 Java 开拓者在消逝JavaScript
时应当掌握的概念和工具。自然地,这里未有提供要学习的全部的手艺项目清单,可是只要你正酌量一条道走到黑地浓郁JavaScript 项目,那会帮衬你起步,拥抱 JavaScript
的极其将拉动你不会频频地消沉。

拉姆da 表明式和 Streams

就像是大家都相比较赏识 Lambda 和 Streams —— Nashorn 也是!纵然 ECMAScript
5.1 中贫乏 Java 8 拉姆da 表明式中的紧缩箭头的语法,但我们能够在承当Lambda 表明式之处选拔函数来代表。

var list2 = new java.util.ArrayList();
list2.add("ddd2");
list2.add("aaa2");
list2.add("bbb1");
list2.add("aaa1");
list2.add("bbb3");
list2.add("ccc");
list2.add("bbb2");
list2.add("ddd1");

list2
    .stream()
    .filter(function(el) {
        return el.startsWith("aaa");
    })
    .sorted()
    .forEach(function(el) {
        print(el);
    });
    // aaa1, aaa2

在JavaScript中调用Java方法十分轻便。大家首先须要定义叁个Java静态方法。

JavaScript
的世袭是依据原型的。即,你从未扩充了其他门类的品种,而实际上,你具有的实例从别的实例世袭了功效。

总结

自己期望那篇文章对您有用,能够令你轻便通晓 Nashorn JavaScript
引擎。更加多关于 Nashorn
的音讯请阅读 这里, 这里 和 这里.
若是您是要用 Nashorn 编写 Shell
脚本的话能够参考 这里.

千古自身也发布了一些 文章 是有关怎么着在
Nashron 引擎中采纳 Backbone.js 模型数据的。假如你想要驾驭越来越多 Java 8
的话能够去拜望我的稿子 Java 8
Tutorial 和 Java
8 Stream
Tutorial.

正文中的示例代码能够透过 GitHub 获取,你可以fork
那些库房并透过 Twitter 来给自家报告。

咬牙编程!

拉姆da表达式和数据流

各样人都热爱lambda和数据流 — Nashron也长期以来!纵然ECMAScript 5.1从未Java8
lmbda表明式的简化箭头语法,大家得以在其他选拔lambda表达式之处使用函数字票面价值。

var list2 = new java.util.ArrayList();list2.add;list2.add;list2.add;list2.add;list2.add;list2.add;list2.add;list2.add;list2 .stream() .filter(function { return el.startsWith; }) .sorted() .forEach(function { print; // aaa1, aaa2

函数式编制程序:一等草木愚夫是函数,实际不是递归

字符串管理

自身爱好字符串裁剪.

print("   hehe".trimLeft());            // hehe
print("hehe    ".trimRight() + "he");   // hehehe

加载脚本

在JavaScript中加载额外的脚本文件丰盛便利。大家得以选取load函数加载本地或远程脚本。

自家在自己的Web前端中山大学量应用Underscore.js,所以让大家在纳什ron中复用它:

load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js');var odds = _.filter([1, 2, 3, 4, 5, 6], function  { return num % 2 == 1;});print; // 1, 3, 5

表面脚本会在相似JavaScript上下文中被实行,所以大家得以一贯访谈underscore
的靶子。要铭记当变量名称互相冲突时,脚本的加载大概会使您的代码崩溃。

这一难点能够通过把脚本文件加载到新的大局上下文来绕过:

loadWithNewGlobal('script.js');

假设您对编写命令行脚本感兴趣,来试一试Nake吧。Nake是叁个Java 8
纳什ron的简化营造筑工程具。你只必要在类型特定的Nakefile中定义义务,之后经过在命令行键入nake -- myTask来实行这么些职分。任务编写为JavaScript,何况在Nashron的本子形式下运作,所以你能够运用你的终点、JDK8
API和任性Java库的整整效用。

对Java开采者来讲,编写命令行脚本是破天荒的轻便…

自己希望这几个课程对您抱有利于,并且你能够分享Nashron
JavaScript引擎之旅。有关纳什ron的越来越多新闻,请见这里、这里和这里。使用Nashron编写shell脚本的教程请见这里。

本身近年发布了一篇一而再小说,关于如何在Nashron中利用Backbone.js模型。如若您想要进一层读书Java8,请阅读小编的Java8课程,和自己的Java8数额流教程。

那篇Nashron教程中的可运维的源代码托管在Github上。请随便fork小编的仓库,或许在Instagram上向自家报告。

请坚忍不拔编制程序!

能够开启 strict 格局。只需在本子文件最上端写上“use
strict”,那么不上心编写的全局变量申明将显得错误。

Import 的范围

突发性,这在壹次性导入多少个java
包时相当低价。大家得以选用JavaImporter并结合with,在with块范围内引用:

var imports = new JavaImporter(java.io, java.lang);
with (imports) {
    var file = new File(__FILE__);
    System.out.println(file.getAbsolutePath());
    // /path/to/my/script.js
}

在向Java传递原生JavaScript对象时,你能够选取ScriptObjectMirror类,它实在是底层JavaScript对象的Java表示。ScriptObjectMirror实现了Map接口,位于jdk.nashorn.api中。这么些包中的类能够用于客商端代码。

最后,你的种类将索要的、相比较关键的是构建筑工程具。假诺您在 Java 项目中使用
JavaScript,请确认保障您能够规避 Java
塑造筑工程具,那就基本上丰裕了。不过,对于单身的 JavaScript
项目,未有须要引进大而无当—Maven【注3】。

参数重载

方式和函数可以行使点符号或方括号来进展调用。

var System = Java.type('java.lang.System');
System.out.println(10);              // 10
System.out["println"](11.0);         // 11.0
System.out["println(double)"](12);   // 12.0

在应用重载的参数来调用方法时得以传递可选参数来确定具体调用了哪个方法,如
println(double卡塔尔。

现在让我们通过传播狂妄Java对象来调用第一个函数:

function forEach (array, action) {
for (var i = 0; i < array.length; i++) {
action (array[i]); //apply action to every element of the arra. }
}

function reduce (combine, base, array) {
forEach (array, function (element) {
base = combine (base, element); // and here we apply function passed as ‘combine’ parameter to ‘base’ and ‘element’ });
return base;
}

function add (a, b) { // btw, this is how you define a function in JavaScript return a + b;
}

function sum (numbers) {
return reduce (add, 0, numbers);
}

正文为通晓全数关于 纳什orn JavaScript 引擎易于通晓的代码例子。 Nashorn
JavaScript 引擎是Java SE 8的一片段,它与别的像谷歌 V8 (它是谷歌(Google卡塔尔国Chrome 和Node.js的斯特林发动机)的单独引擎相互角逐。 Nashorn
增加了Java在JVM上运营动态JavaScript脚本的力量。

var fun1 = function { print('Hi there from Javascript, ' + name); return "greetings from javascript";};var fun2 = function  { print("JS Class Definition: " + Object.prototype.toString.call;};

还大概有,作者不想太长远项目和布尔值的争辨,不过要警醒 JavaScript
引擎扔给你的隐式类型转变。

ScriptObjectMirror

当使用ScriptObjectMirror把地点JavaScript对象传入时,实际上是有叁个java对象表示JavaScript
对象。 ScriptObjectMirror
完结了接口与jdk.nashorn.api其间的映射。这一个包下的类目标固然用来顾客端代码使用。

下二个演示订正参数类型Object为ScriptObjectMirror,由此我们能博获得传播JavaScript中目的的一部分消息:

static void fun3(ScriptObjectMirror mirror) {
    System.out.println(mirror.getClassName() + ": " +
        Arrays.toString(mirror.getOwnKeys(true)));
}

当大家把传递对象hash到方式中,在Java端就能够访谈这几个属性:

MyJavaClass.fun3({
    foo: 'bar',
    bar: 'foo'
});

// Object: [foo, bar]

我们也足以在Java端调用JavaScript对象中的函数。大家先是定义三个JavaScript类型
Person,满含属性 firstName 、lastName 和函数getFullName。

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.getFullName = function() {
        return this.firstName + " " + this.lastName;
    }
}

javascript 函数getFullName 能被 ScriptObjectMirror
callMember()调用。

static void fun4(ScriptObjectMirror person) {
    System.out.println("Full Name is: " + person.callMember("getFullName"));
}

当大家传入一个新的person给java 方法时,大家能在调节台看到预期结果:

var person1 = new Person("Peter", "Parker");
MyJavaClass.fun4(person1);

// Full Name is: Peter Parker

Nashorn的当下政策遵守ECMAScript标准。当我们在JDK8中透露它时,它将基于ECMAScript
5.1。Nashorn以往的机要公布基于ECMAScript 6。

对此此外一个门类,你都想运转一些测量检验。测量试验对于动态类型的言语更是关键,最棒选用一种测量试验框架。笔者推荐 Jasmine,它是用来测验JavaScript 的一颦一笑使得开拓框架。

在哪里

防止忘记您在哪个地方:

print(__FILE__, __LINE__, __DIR__);

JavaScript原始类型调换为适当的Java包装类,而JavaScript原生对象会接受在那之中的适配器类来代表。要记住jdk.nashorn.internal中的类大概会全数扭转,所以不该在客商端面向那个类来编制程序。

断定,你早已清楚了 Java 和
JavaScript,不管它们有着多么肖似的命名,互相没有分享太多共通之处。Java
的静态类型、切合间接规律的简要语法和冗长,与 JavaScript
的动态、贫乏一致性原则和奇异,有着宏大的不等。

集合与For Each

大家得以行使java的集纳来代替数组。首先定义使用 Java.type概念一个java类型,而后依据须求创制三个实例。

var ArrayList = Java.type('java.util.ArrayList');
var list = new ArrayList();
list.add('a');
list.add('b');
list.add('c');

for each (var el in list) print(el);  // a, b, c

为了遍历集结和数组中的成分,Nashorn 引进了 for each 语句。那就好像 Java
的 for 循环同样。

这里是二个对集合成分进行遍历的例证,使用的是 :

var map = new java.util.HashMap();
map.put('foo', 'val1');
map.put('bar', 'val2');

for each (var e in map.keySet()) print(e);  // foo, bar

for each (var e in map.values()) print(e);  // val1, val2
invocable.invokeFunction("fun2", new Date;// [object java.util.Date]invocable.invokeFunction("fun2", LocalDateTime.now;// [object java.time.LocalDateTime]invocable.invokeFunction("fun2", new Person;// [object com.winterbe.java8.Person]

持续:就疑似真正的社会风气

品类数组

原始javascript 数组时无类型的。 Nashorn
运营你在JavaScript中利用java数组:

var IntArray = Java.type("int[]");

var array = new IntArray(5);
array[0] = 5;
array[1] = 4;
array[2] = 3;
array[3] = 2;
array[4] = 1;

try {
    array[5] = 23;
} catch (e) {
    print(e.message);  // Array index out of range: 5
}

array[0] = "17";
print(array[0]);  // 17

array[0] = "wrong type";
print(array[0]);  // 0

array[0] = "17.3";
print(array[0]);  // 17

int[] 数组的行事像二个真正的 java int
数组。 但当我们筹划增添非整数的值的数组时,Nashorn
会推行隐式类型转变。 字符串会自行转变为int,这一定有益。

在接下去的15分钟内,你会学到怎样在JVM上在运转时动态试行JavaScript。小编会使用小段代码示例来演示最新的Nashron语言特色。你会学到怎样在Java代码中调用JavaScript函数,也许相反。最终你会酌量好将动态脚本集成到你的Java平日业务中。

列出离谱赖的 JavaScript 设计上的支配比想象中要便于。在 JavaScript
程序中要制止的最显眼的地点正是全局变量的阐明

言语扩张

纳什orn 定义一密密层层的语言和扩展了 ECMAScript
规范的API。 让大家一贯进去新型的效用:

static void fun4(ScriptObjectMirror person) { System.out.println("Full Name is: " + person.callMember("getFullName"));}

我们力所不如在一篇博文里解释 JavaScript 的富有细节。假诺你正或多或少地关系了
web 应用程序开荒,那么,大家的 Java
工具和技能节制报告宣布了,大好些个(71%)Java
开垦者被归到了这一类,只是你对 JavaScript 境遇了掣肘。

扩展类

Java
的花色能够省略的经过 Java.extend 实行扩充,在下个例证你将在本子中创设三个四线程示例:

var Runnable = Java.type('java.lang.Runnable');
var Printer = Java.extend(Runnable, {
    run: function() {
        print('printed from a separate thread');
    }
});

var Thread = Java.type('java.lang.Thread');
new Thread(new Printer()).start();

new Thread(function() {
    print('printed from another thread');
}).start();

// printed from a separate thread
// printed from another thread

图片 2

没有须要置疑 JavaScript 是 web
编程语言,是非常多别样语言的编写翻译目的,也是用来表明有时候大家只是想具有更加多自由时间的极点方法。纵然如此,那不是一件坏事。每一台能够浏览今世网址的微处理器都配备了独具质量和可用的
JavaScript 引擎。最重点的是,JavaScript 代码能够在后端运转。

Java调用Javascript 函数

Nashorn
协理java代码直接调用定义在本子文件中JavaScript函数。你能够把java对象作为函数的参数且在调用函数的java方法中摄取重回的数量。

通常来说的JavaScript代码将会在java端调用:

var fun1 = function(name) {
    print('Hi there from Javascript, ' + name);
    return "greetings from javascript";
};

var fun2 = function (object) {
    print("JS Class Definition: " + Object.prototype.toString.call(object));
};

为了调用函数,你首先得把脚本引擎转变为 Invocable。NashornScriptEngine 完结了 Invocable
接口且定义八个调用JavaScript函数的章程 invokeFunction ,传入函数名就能够。

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("script.js"));

Invocable invocable = (Invocable) engine;

Object result = invocable.invokeFunction("fun1", "Peter Parker");
System.out.println(result);
System.out.println(result.getClass());

// Hi there from Javascript, Peter Parker
// greetings from javascript
// class java.lang.String

上述代码的实行将要调整台打字与印刷三行音信。调用 print
函数将出口内容通过管道送到 System.out 调节台,因而大家先是观望的是
JavaScript打字与印刷的新闻。

当今咱们经过传递任意的 Java 对象去调用第一个函数:

invocable.invokeFunction("fun2", new Date());
// [object java.util.Date]

invocable.invokeFunction("fun2", LocalDateTime.now());
// [object java.time.LocalDateTime]

invocable.invokeFunction("fun2", new Person());
// [object com.winterbe.java8.Person]

你能够传递大肆 Java 对象而不会在 JavaScript
那边错过类型音讯。因为脚本本身是在 JVM 设想机中举行的,大家得以完全使用
nashorn 引擎的 Java API 和表面库的不战而屈人之兵作用。

Nashorn
扶持从Java代码中央政府机构接调用定义在本子文件中的JavaScript函数。你能够将Java对象传递为函数参数,并且从函数重回数据来调用Java方法。

能够设想的 JavaScript
项目用到的构建筑工程具是 GulpJS【注4】。它是基于插件的创设系统,你可感到其钦命任务。职分可以是“拷贝
src 目录下的 .js 文件到 dest”、或“压缩小编的 JavaScript
代码用于分娩处境”。令人受到触动的是,GulpJS
把职责相关的文书流步入过滤器,由此你能够把地点的七个任务加入一回有效的清扫中。

指令行脚本

假若你对用 Java
编写命令行脚本很感兴趣的话,能够试试 Nake 。Nake
是贰个为 Java 8 Nashorn 希图的大约 Make 工具。你能够在 Nakefile
文件中定义职责,然后使用 nake — myTask 来运营职责。职务采纳 JavaScript
编写并因此 Nashorn 脚本方式运转,由此你能够让您的终点应用完全选拔 Java 8
API 和任何 Java 库强盛的法力。

对 Java 开辟者来讲,编写命令行脚本一向不曾那样简约过。

Nashorn定义了多种对ECMAScript标准的言语和API扩张。让我们看一看最新的特点:

REPL 代表“读取-求值-输出”循环(Read-Eval-Print
Loop)【注2】,是无数动态语言的刚劲工具。若是您看过 Scala 或
Groovy,你早晚能够精通那几个定义。

在 JavaScript 端调用 Java 方法

在 JavaScript 中调用 Java 方法相当的粗略。首先我们定义多个静态的 Java 方法:

static String fun1(String name) {
    System.out.format("Hi there from Java, %s", name);
    return "greetings from java";
}

JavaScript 可透过 Java.type API 来援用 Java 类。那跟在 Java
类中引进别的类是看似的。当定义了 Java 类型后大家可径直调用其静态方法
fun1(State of Qatar 并打印结果到 sout。因为方法是静态的,所以大家不须要成立类实例。

var MyJavaClass = Java.type('my.package.MyJavaClass');

var result = MyJavaClass.fun1('John Doe');
print(result);

// Hi there from Java, John Doe
// greetings from java

当调用java
方法时,Nashorn如何管理原生JavaScript类型与java类型调换?让我们用一个简短的事例来开采。

上面包车型地铁java方法轻便易行打字与印刷实际的类措施参数的连串:

static void fun2(Object object) {
    System.out.println(object.getClass());
}

为了然引擎如哪个地区理类型调换,作者动用分歧JavaScript类型来调用java方法:

MyJavaClass.fun2(123);
// class java.lang.Integer

MyJavaClass.fun2(49.99);
// class java.lang.Double

MyJavaClass.fun2(true);
// class java.lang.Boolean

MyJavaClass.fun2("hi there")
// class java.lang.String

MyJavaClass.fun2(new Number(23));
// class jdk.nashorn.internal.objects.NativeNumber

MyJavaClass.fun2(new Date());
// class jdk.nashorn.internal.objects.NativeDate

MyJavaClass.fun2(new RegExp());
// class jdk.nashorn.internal.objects.NativeRegExp

MyJavaClass.fun2({foo: 'bar'});
// class jdk.nashorn.internal.scripts.JO4

土生土养的javascript 类型被改造为方便的 java
包装器类。并非本地javascript对象内部适配器类。请记住,那些类来自于jdk.nashorn.internal,所以你不应当在客户端应用这几个类:

Anything marked internal will likely change out from underneath
you.

本条课程中,你会通过轻易易懂的代码示例,来打探Nashorn
JavaScript引擎。Nashorn JavaScript引擎是Java SE 8
的一局地,并且和其余独立的引擎举例Google V8(用于GoogleChrome和Node.js的斯特林发动机)相互角逐。Nashorn通过在JVM上,以原生格局运维动态的JavaScript代码来增添Java的功效。

JavaScript
中的函数是第一类公民,它们是值,可被储存在变量里、传递给别的函数、在适用的时候再实施。

数组转换

某些包时能够直接使用而不必利用 Java.type 或JavaImporter引入,如 java.util:

var list = new java.util.ArrayList();
list.add("s1");
list.add("s2");
list.add("s3");

如下的代码演示了将java list转变为JavaScript的数组:

var jsArray = Java.from(list);
print(jsArray);                                  // s1,s2,s3
print(Object.prototype.toString.call(jsArray));  // [object Array]

别的的方法:

var javaArray = Java.to([3, 5, 7, 11], "int[]");
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");engine.eval(new FileReader("script.js"));Invocable invocable = (Invocable) engine;Object result = invocable.invokeFunction("fun1", "Peter Parker");System.out.println;System.out.println(result.getClass;// Hi there from Javascript, Peter Parker// greetings from javascript// class java.lang.String

REPL

调用父类函数

在 JavaScript 中做客重载的成员会有一小点难堪,因为 ECMAScript 未有看似
Java 的 super 关键字一样的东西。所幸的是 Nashorn 有方法消除。

第一大家在 Java 代码中定义多个超类:

class SuperRunner implements Runnable {
    @Override
    public void run() {
        System.out.println("super run");
    }
}

接下去大家在 JavaScript 中重载 SuperRunner 。创立三个新的 Runner
实例时请小心 Nashorn 的扩展语法:其重载成员的语法是参照 Java
的无名对象的做法。

var SuperRunner = Java.type('com.winterbe.java8.SuperRunner');
var Runner = Java.extend(SuperRunner);

var runner = new Runner() {
    run: function() {
        Java.super(runner).run();
        print('on my run');
    }
}
runner.run();

// super run
// on my run

我们接收Java.super调用了重载方法 SuperRunner.run()。

在JavaScript中实践别的脚本是丰裕便于的。我们能够load函数载入本地或远程的本子。

在本身的浩大web前端中都采纳了 Underscore.js ,因而在Nashorn中我们能够援用Underscore:

load('http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js');

var odds = _.filter([1, 2, 3, 4, 5, 6], function (num) {
    return num % 2 == 1;
});

print(odds);  // 1, 3, 5

增加脚本的实施是在同叁个 JavaScript 上下文中,因而大家得以平昔访谈underscore 变量。记住脚本的加载只怕会因为变量名的交汇诱致代码出难题。

大家得以经过将加载的台本文件放置到二个新的全局上下文来减轻那几个难点:

loadWithNewGlobal('script.js');
static void fun2(Object object) { System.out.println(object.getClass;}

结论

var person1 = new Person("Peter", "Parker");MyJavaClass.fun4;// Full Name is: Peter Parker

正如自个儿上面提到的,在编制程序上要非常在乎这种语言的语法和特别,而不只是掌握。项目非常少由于语言的不足而未果,越来越多的挫败是与完整品种框架不足有关。上边是推进你提交项目标一对工具。

Java Beans

你能够回顾地选取品质名称来向Java
Beans获取或设置值,没有需求显式调用读写器:

var Date = Java.type('java.util.Date');var date = new Date();date.year += 1900;print(date.year); // 2014

科学,代码品质,对于别的开垦者来讲,最要紧的办事就是交付。不过不用在品质上迁就,不要对您付出的代码认为不自信就不情愿与同事分享。

$ cd /usr/bin$ ln -s $JAVA_HOME/bin/jjs jjs$ jjsjjs> print('Hello World');

图片 3

性情绑定

七个例外目的的天性能够绑定到联合:

var o1 = {};var o2 = { foo: 'bar'};Object.bindProperties;print; // baro1.foo = 'BAM';print; // BAM

大家将要本文蕴含下列语言等第的技巧点:

咱俩也可以在Java中调用JavaScript的成员函数。让我们率先定义JavaScript
Person项目,带有属性firstNamelastName,以致艺术getFullName

另七个相比便利的工具是 jjs,它包扎在 JDK1.8。

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");engine.eval("print('Hello World!');");
  • JavaScript 的通用性
  • JavaScript 的函数编制程序难点
  • 不同于 Java 的继承

当向那几个格局传递对象时,在Java端能够访谈其性质:

是因为每台Computer运行时都可收获的轻松,JavaScript 成为 Java 体验的完善连续。

上边包车型大巴例证将参数类型从Object改为ScriptObjectMirror,所以我们得以从传出的JavaScript对象中拿走部分音信。

很明显这里不是要付出教程,不过自身想让您一瞥 JavaScript
代码看起来是何等地温婉。Jasmine 是 JavaScript
项目最佳的举行之一,大家指挥若定在成品开拓中运用到了 ZeroTurnaround
项目,极度是对此满含 JavaScript
的不间断运转的相互剖析器 XRebel。

导入作用域

偶然贰次导入七个Java包会很便利。大家能够运用JavaImporter类,和with言语一同行使。全数被导入包的类公事都能够在with话语的局地域中做客到。

var imports = new JavaImporter(java.io, java.lang);with  { var file = new File; System.out.println(file.getAbsolutePath; // /path/to/my/script.js}

那不是尚未基于的,上面是在 JavaScript 里定义二个 reduce
函数的例子,来自于《Eloquent JavaScript》一书。

下面包车型客车Java方法大致打印了主意参数的莫过于类型:

JavaScript 与 Java
另三个根本的分裂点在于,前边八个是动态类型语言,其真谛是怀有东西都足以是任何类型。那很明朗了,实在不可能再重申了:无须针对分裂系列的值,去复用相通的变量

为了知道背后如哪里理类型调换,大家利用区别的JavaScript类型来调用这些点子:

图片 4

为了在Java中实践JavaScript,你首先要由此javax.script包创制脚本引擎。这一个包已经在Rhino(来源于Mozilla、Java中的遗留JS引擎)中采取了。

本人不太分明 Java
开荒者应该从当中吸收什么,不过要小心世襲形式的不等,对于父级对象要那么些上心、而不要离奇乡改变整个程序的作为。

下边包车型地铁JavaScript函数稍后会在Java端调用:

再有大量的可用插件,依赖适当的构建系统,你将发掘项目中的同盟会轻易相当多。

Java对象在流传时不会在JavaScript端损失任何类型消息。由于脚本在JVM上原生运转,我们得以在Nashron上使用Java
API或外界库的百分百功效。

化解专门的学业的小提醒

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");engine.eval(new FileReader("script.js"));

它是命令行工具,允许你走访 JDK 中的 Nashorn JavaScript
引擎,完全有力量执行那些甚格外端严谨的 JavaScript 脚本。

static void fun3(ScriptObjectMirror mirror) { System.out.println(mirror.getClassName() + ": " + Arrays.toString(mirror.getOwnKeys;}

优点

立异 –
作者今后正值编写制定用于浏览器的Java8数据流API的JavaScript实现。假若你对此感兴趣,请在Github上访谈Stream.js。极其盼望你的申报。

编排三遍,差不离随地运转!

原文:Java 8 Nashorn Tutorial

译者:飞龙

协议:CC BY-NC-SA 4.0

别的时候要幸免的

MyJavaClass.fun2;// class java.lang.IntegerMyJavaClass.fun2;// class java.lang.DoubleMyJavaClass.fun2;// class java.lang.BooleanMyJavaClass.fun2("hi there")// class java.lang.StringMyJavaClass.fun2(new Number;// class jdk.nashorn.internal.objects.NativeNumberMyJavaClass.fun2(new Date;// class jdk.nashorn.internal.objects.NativeDateMyJavaClass.fun2(new RegExp;// class jdk.nashorn.internal.objects.NativeRegExpMyJavaClass.fun2({foo: 'bar'});// class jdk.nashorn.internal.scripts.JO4
  • 注1:在Computer科学里,尾调用是指三个函数里的终极一个动作是四个函数调用的场合:即这几个调用的再次回到值直接被日前函数重返的气象。这种情状下称该调用地方为尾地方。若这几个函数在尾地方调用自家(或是八个尾调用自家的别的函数等等),则称这种情景为尾递归,是递归的一种奇特别情报况。尾调用不自然是递归调用,但是尾递归非常有用,也正如便于完毕。http://zh.wikipedia.org/wiki/尾调用
  • 注2:REPL 是叁个简易的,人机联作式的编制程序处境。那几个词平时用于代替一个Lisp 的人机联作式开拓条件,但也能指代命令行的情势和诸如 APL, BASIC,
    Clojure, F#, Haskell, J, Julia, Perl, PHP, Prolog, Python, 揽胜,
    Ruby, Scala, Smalltalk, Standard ML, Tcl, Javascript
    那样的编制程序语言切磋所享有的形似的编制程序境况。那也被称做人机联作式顶层零件(interactive
    toplevel)。
  • 注3:Maven 除了以程序创设技巧为特色之外,还提供 Ant
    所缺乏的高级项目管理工科具。由于 Maven
    的缺省创设法规有较高的可重用性,所以通常用两三行 Maven
    营造脚本就足以营造轻便的类型,而接收 Ant 则供给十几行。事实上,由于
    Maven 的面向项目的主意,好些个 Apache Jakarta 项目今后接纳Maven,而且公司项目选取 Maven
    的比例在不停增强。
  • 注4:从头编写 HTMLCSSJavascript 是上个世纪的业务了,近些日子的
    JavaScript 都以经过 CoffeeScript
    那样的支持句法缩写的编辑器写成的。若是您愿意写完 JavaScript
    能够三个工具达成代码清理优化工作,Gulp 正是您的不二之选,GulpJS 相仿Ant 或 Maven 之于 Java。

品类数组

JavaScript的原生数组是无类型的。Nashron允许你在JavaScript中运用Java的体系数组:

var IntArray = Java.type;var array = new IntArray;array[0] = 5;array[1] = 4;array[2] = 3;array[3] = 2;array[4] = 1;try { array[5] = 23;} catch  { print(e.message); // Array index out of range: 5}array[0] = "17";print; // 17array[0] = "wrong type";print; // 0array[0] = "17.3";print; // 17

int[]数组就像是真正的Java整数数组那样。可是别的,在我们准备向数组增添非整数时,Nashron在私行实行了有的隐式的转移。字符串会自动调换为整数,那非常有利。

这张开了函数式编程世界的大门,那是布局化 JavaScript 编制程序的完备方式。

MyJavaClass.fun3({ foo: 'bar', bar: 'foo'});// Object: [foo, bar]

盯住刚以前是个 string 类型的变量,可是现在它成了浮点数、或许函数了,相信本人!

Nashorn定义了大批量对ECMAScript标准的言语和API扩充。可是首先让大家看一看Java和JavaScript代码怎样相互。

想像一下,对象A有如二个映射,我们刚刚微微提到了部分、可是用了分裂的眼光,然后另多少个好像映射的对象B从A世襲了全方位。

别的标识为“内部”的事物都大概会从您那边产生改换。

侥幸的是,JavaScript 有一套得体的技术方案——JSHint。JSHint 是为
JavaScript 量身创设的静态解析工具,与应用于 Java 代码的 FindBug
相仿。JSHint
能够在您的代码库运维,并高亮出思疑的或不符合规律的地点,纵然你不会及时产生bug,但那么些地点未来变得难以保险。在品种中援助它一定简单。帮团结多个忙——如果你在写
JavaScript 代码,就用 JSHint 让它更安全、少一些两难。

JavaScript代码既能由此传递JavaScript代码字符串,也得以传递指向您的JS脚本文件的FileReader来执行:

你领悟让 JS
开拓者走向欢娱的心腹或特级试行吧?无庸置疑应该去享受!在底下争辨或在
Facebook:@shelajev 上与自个儿交谈。作者甘愿听到你的主张!

Nashorn JavaScript基于ECMAScript 5.1,不过它的接续版本会对ES6提供支撑:

此外,你会找到一些工具方面包车型地铁推荐,没有那么些工具,你是不想伊始 JavaScript
项目标,满含了营造系统的代码品质解析和测量检验框架方面包车型客车工具。

做客超类

在JavaScript中做客被掩没的积极分子经常相比辛劳,因为Java的super关键字在ECMAScript中并海市蜃楼。幸运的是,Nashron有一套补救措施。

首先大家要求在Java代码中定义超类:

class SuperRunner implements Runnable { @Override public void run() { System.out.println("super run"); }}

上面作者在JavaScript中覆盖了SuperRunner。要小心创设新的Runner实例时的Nashron语法:覆盖成员的语法取自Java的佚名对象。

var SuperRunner = Java.type('com.winterbe.java8.SuperRunner');var Runner = Java.extend(SuperRunner);var runner = new Runner() { run: function() { Java.super.run(); print('on my run'); }}runner.run();// super run// on my run

咱俩由此Java.super()扩充调用了被掩瞒的SuperRunner.run()方法。

放置到大家保养的 JVM 的、轻量级高品质 JavaScript 运维时
Nashorn,完全能够分解 JavaScript 脚本,还是能够够表达项目中包涵 Java 代码的
JavaScript 脚本。

Nashorn
JavaScript引擎能够在Java代码中编制程序调用,也得以通过命令行工具jjs使用,它在$JAVA_HOME/bin中。假诺计划接收jjs,你恐怕希望设置符号链接来简化访谈:

本文,作者不想只是漫谈 JavaScript
的好与倒霉,或另行任何人都能免费找到的、不胜枚举的 JavaScript
教程。笔者想列出有个别有利于精晓 JavaScript
做为一种语言的技能点,并从临近 horse 的角度来明白。

本条课程专一于在Java代码中调用Nashron,所以让我们先跳过jjs。Java代码中轻巧的HelloWorld如下所示:

只顾,在 JavaScript 里,无论怎么样时候,不利用 var
关键词定义变量,那么定义的变量被推到了它们被定义的作用域最上端。那意味,各个用这种办法定义的变量将跑到全局范围顶上部分,那会吸引冲突以至你和同事不可预期的憎恶。

static String fun1(String name) { System.out.format("Hi there from Java, %s", name); return "greetings from java";}

不过,JavaScript 是 web 的编制程序语言,最近出于 Node.js 和 JVM 本人的
Nashorn JavaScript 引擎的腾飞,在劳务器端取得了一对一的瞩目。

聚拢和界定遍历

咱们能够利用其余Java集合,而制止使用数组瞎折腾。首先需求通过Java.type定义Java类型,之后创建新的实例。

var ArrayList = Java.type('java.util.ArrayList');var list = new ArrayList();list.add;list.add;list.add;for each (var el in list) print; // a, b, c

为了迭代群集和数组,Nashron引进了for each言语。它就如Java的限量遍历那样行事。

下边是另二个成团的界定遍历示例,使用HashMap

var map = new java.util.HashMap();map.put('foo', 'val1');map.put('bar', 'val2');for each (var e in map.keySet print; // foo, barfor each (var e in map.values print; // val1, val2

那表达B能够访谈A全体片段:A的法子、字段等等。

类的后续

Java类型能够由Java.extend大肆扩张。就疑似你在下边包车型地铁例证中看出的那么,你居然足以在你的剧本中开创四线程的代码:

var Runnable = Java.type('java.lang.Runnable');var Printer = Java.extend(Runnable, { run: function() { print('printed from a separate thread'); }});var Thread = Java.type('java.lang.Thread');new Thread(new Printer.start();new Thread(function() { print('printed from another thread');}).start();// printed from a separate thread// printed from another thread

创设筑工程具

字符串去空白

自个儿赏识去掉空白的字符串:

print(" hehe".trimLeft; // heheprint("hehe ".trimRight; // hehehe

扭动,这使得函数式编制程序尤其便利:涉及到小的、可分晓函数和不改变的数据结构是在
JavaScript 里运维的法子。

位置

防御你忘了谐和在何地:

print(__FILE__, __LINE__, __DIR__);

测试

实行这段代码会在调控台产生三行结果。调用函数print将结果输出到System.out,所以大家会首先观察JavaScript输出。

在 Jasmine,你用 describe
描述测验套件,它阻挡了你想测量试验的代码访谈。在测量试验中的代码达成后,你
expect 一些结实。

为了调用函数,你首先须要将脚本引擎转变为InvocableInvocable接口由NashornScriptEngine贯彻,并且定义了invokeFunction方法来调用钦赐名称的JavaScript函数。

只顾:大家尚无在此运用 reduce 的递归版本。JavaScript
没有以尾调用【注1】为特点,那象征每种函数的递归版本都将用到栈的深浅,和
Java 相像,要是您递归太深,程序就崩溃。

Java类能够因此Java.typeAPI扩展在JavaScript中引用。它就和Java代码中的import就好像。只要定义了Java类型,大家就可以自然地调用静态方法fun1(),然后像sout打字与印刷消息。由于措施是静态的,大家无需首先创造实例。

在执行中,笔者有史以来未有看出有人实际行使简便的基于原型的继续。经常当某一个人需求继续时,他只是布局类,由此你能够用到具备科学普及的技艺,和依照类的接续的办事方式。

——雷内 Saarsoo,XRebel 前端技术员

参数重载

艺术和函数能够由此点运算符或方括号运算符来调用:

var System = Java.type('java.lang.System');System.out.println; // 10System.out["println"]; // 11.0System.out["println"]; // 12.0

当使用重载参数调用方法时,传递可选参数类型println会钦赐所调用的具体方法。

函数字票面价值

对此简易的单行函数,大家能够去掉花括号:

function sqr x * x;print; // 9

当向Java方法传递新的Person时,我们会在调整台见到预期的结果:

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图