JavaScript (Rhino) use library or include other scripts

对着背影说爱祢 提交于 2019-11-29 23:00:36

I think you're after the load() method/property of Rhino's global object/scope

load("file1.js");
load("file2.js");
load("file3.js");

methodFromFileOne();
var bar = methodFromFileTwo();
var etc = dotDotDot();

This will load a javascript source file, similar to how include/require will in PHP. Once you load a file, you'll be able to call and function or use any object defined in the loaded file.

This is how things work when you're using the Rhino shell, which is the only context I know (your question mentioned the Java SDK, which is outside my area of experience)

if you happen to be trying to do this within ant, you might see this error:

<script language="javascript">
    load('foo.js');
</script>
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function load.

but you can sidestep it:

<script language="javascript">
    eval(''+new String(org.apache.tools.ant.util.FileUtils.readFully(new java.io.FileReader('foo.js'))));
</script>

A real-life example this time, i.e. running the esprima parser with Rhino 1.7R4.

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
...

Context context = Context.enter();
Scriptable globalScope = context.initStandardObjects();
Reader esprimaLibReader = new InputStreamReader(getClass().getResourceAsStream("/esprima.js"));
context.evaluateReader(globalScope, esprimaLibReader, "esprima.js", 1, null);

// Add a global variable out that is a JavaScript reflection of the System.out variable:
Object wrappedOut = Context.javaToJS(System.out, globalScope);
ScriptableObject.putProperty(globalScope, "out", wrappedOut);

String code = "var syntax = esprima.parse('42');" +
    "out.print(JSON.stringify(syntax, null, 2));";

// The module esprima is available as a global object due to the same
// scope object passed for evaluation:
context.evaluateString(globalScope, code, "<mem>", 1, null);
Context.exit();

After running this code, you should see the output as follows:

{
  "type": "Program",
  "body": [
    {
      "type": "ExpressionStatement",
      "expression": {
        "type": "Literal",
        "value": 42,
        "raw": "42"
      }
    }
  ]
}

So indeed, the trick is in reusing the globalScope object.

As long as you use the same scope to execute each file, they will be able to reference functions and variables from previously executed files.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!