JavaScript (Rhino) use library or include other scripts

前端 未结 4 735
野趣味
野趣味 2020-12-24 06:44

In JDK6, is there a way to load multiple scripts, each in a file, and have the one script reference a method of another script? Sort of like \"include\"?

相关标签:
4条回答
  • 2020-12-24 07:06

    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)

    0 讨论(0)
  • 2020-12-24 07:08

    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.

    0 讨论(0)
  • 2020-12-24 07:11

    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.

    0 讨论(0)
  • 2020-12-24 07:23

    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>
    
    0 讨论(0)
提交回复
热议问题