用Nashorn实现模块模式
Implementing the module pattern with Nashorn
我在Java 8上研究了Nashorn,它的功能和它给开发人员提供的功能给我留下了深刻的印象。
出于对JavaScript代码组织的兴趣,我想我应该尝试揭示模块模式。
this._sys =
(function(){
function hello() {
print('hello world!');
}
return {
hello: hello
};
})();
_sys.hello();
将js代码保存在main.js
中。当我使用js时,上面的代码可以完美地工作。但是当我尝试通过Groovy/Java运行相同的代码时,它失败了。有人知道为什么会失败吗?
在Groovy中测试:
class Test {
public static void main(String[] args) {
def engine = new ScriptEngineManager().getEngineByName("nashorn")
engine.eval(new FileReader("E:/main.js"));
println engine.context.getAttribute("_sys")
def invocable = engine as Invocable
def x = invocable.invokeFunction("this._sys.hello",null)
println x
}
}
错误:Exception in thread "main" java.lang.NoSuchMethodException: No such function this._sys.hello
at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:184)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:508)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:229)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
at Test.main(Test.groovy:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
这个问题来自于sys
实际上是JavaScript引擎的一个类的实例。hello
不再是一个函数,而是这个类的一个方法,所以你需要使用Invocable.invokeMethod
,通过传递类的实例,如context.getAttribute("_sys")
所返回的,以及方法的名称。
这是一个工作代码:
class Test {
public static void main(String[] args) {
def engine = new ScriptEngineManager().getEngineByName("nashorn")
engine.eval(new FileReader("E:/main.js"));
def sys = engine.context.getAttribute("_sys")
println sys
def invocable = engine as Invocable
def x = invocable.invokeMethod(sys, "hello")
println x
}
}
作为一个例子,您可以从下面的Oracle文章中阅读mustache.js
示例:Oracle Nashorn:用于JVM的下一代JavaScript引擎
相关文章:
- Javascript,访问一个主要对象模块模式中的每个对象
- 模块模式和这个
- 显示模块模式在Knockout中设置模型的新实例
- Javascript中的模块模式和揭示模块模式是否仅在创建API时有用;s
- 用于多个选项卡和模块化的knockoutjs设计模式
- JavaScript模块模式-如何在使用对象/函数之前激发构造函数/init函数
- TypeScript代码类似于揭示模块模式结构
- 为什么在javascript中的模块模式中实现Lazy函数时范围会发生变化
- JavaScript:模块模式差异
- 显示模块模式中的私有成员
- 如何将window.setTimeout与javascript和模块模式一起使用
- j查询模块模式未命名 |如何访问“$”
- 挖空和显示模块模式的数据绑定问题
- 传递参数时如何避免模块模式中的 getter/setter 函数
- 将变量传递给 Javascript 模块化模式方法
- JavaScript 模块模式给出了意想不到的结果
- 从模块模式开始
- 试图通过模块模式在DOM元素上实现change()事件
- 揭示模块模式、KnockoutJS和CoffeeScript
- JavaScript 设计模式:模块模式和揭示模块模式之间的区别