3

まず、私が JavaScript の初心者であることを認めることから始めましょう。したがって、質問は基本的にあまり適切ではない可能性があり、私を助けるのに十分な情報が不足している可能性があります.

バックグラウンド

私の組織には、JavaScript 用の内部 Eclipse ベースの IDE があります。JavaScript でスクリプトを記述し、直接実行するだけです。いくつかの例外のスタック トレースで見たので、Rhino を使用していると思います。

私のコードは 3 つの「.js」ファイルで実行されます。

スクリプト 1: グローバル変数を宣言し、それらを Java オブジェクトとしてインスタンス化する

importClass(java.util.HashMap);
var hmTCResult = new HashMap();

スクリプト 2: スクリプト 1 のグローバル変数を使用していくつかのアクションを実行する

Script-2.prototype.run = function() {
hmTCResult.put("Result", "Fail");
};

changeStatus = function(strStatus){
hmTCResult.put("Result", strStatus);
};

スクリプト 3: グローバル変数を使用するスクリプト 2 の関数を呼び出す

changeStatus("Pass") 

問題定義

スクリプト 3 からスクリプト 2 の関数を呼び出すと、インスタンス変数が選択されないようで、関数が失敗します。つまり、「hmTCResult がオブジェクトのインスタンスに設定されていません」という例外が発生します。同じ変数 hmTCResult がスクリプト 1 でうまく機能することに注意してください。

JavaScript でスコープとコンテキストをいくつか読みましたが、IDE で明示的に表示されないため、突破できませんでした。

必要に応じて、さらに情報を提供させていただきます。

4

3 に答える 3

1

これは問題なく動作します。スコープを調整して、プロトタイプ検索をセットアップするだけです。

Context cx = Context.enter();
try {
    // Cache and reuse:
    ScriptableObject sealedSharedScope = cx.initStandardObjects(null,
            true);
    // Force the LiveConnect stuff to be loaded.
    String loadMe = "RegExp; getClass; java; Packages; JavaAdapter;";
    cx.evaluateString(sealedSharedScope, loadMe, "preLoadLazyLoad", 0,
            null);

    cx.evaluateString(sealedSharedScope, "varInRoot = 'blah';",
            "setVarInRoot", 0, null);

    // here you can put more cx.evaluateString calls to set up your
    // environment (eg. hmTCResult)

    // now connect a throw-away new scope into the hierarchy, with local
    // vars:
    Scriptable scope = cx.newObject(sealedSharedScope);
    // ensure that definitions in the root scope are found
    scope.setPrototype(sealedSharedScope);
    // ensure that new global variables are created in this scope (don't
    // use
    // var for them!)
    scope.setParentScope(null);

    cx.evaluateString(scope, "localVar = varInRoot;", "mySource", 0,
            null);
    assertEquals("blah", scope.get("localVar", scope).toString());
    // new var not in root:
    assertEquals(ScriptableObject.NOT_FOUND,
            sealedSharedScope.get("localVar", scope));
} finally {
    Context.exit();
}

scope.get はプロトタイプ チェーンを検索しないことに注意してください。自分で検索する必要があります。

スコープは Context から独立しており、Context.exit() の後も存続します。

于 2012-11-27T17:59:58.563 に答える
0

Javaでjsスクリプトを評価するには、次の操作を実行できます。

ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType( "text/javascript" );
Bindings bindings = engine.getBindings( ScriptContext.GLOBAL_SCOPE );
bindings.put( "varname", ... );
bindings.put( ... );
engine.put( ScriptEngine.FILENAME, script.toString());
engine.eval( new FileReader( script ));

3つのスクリプトが同じエンジン/バインディング内にロードされている場合は問題ありませんが、script3を実行するためにエンジンが新たに割り当てられている場合、コンテキストはクリアされています。

この投稿は実際には答えではありませんが、コメントするには長すぎます。

于 2012-10-22T21:41:42.690 に答える
0

私の推測では、これ以上の情報はなく、変更されたトランスクリプトが完全に正しいと仮定すると、スクリプトはすべてグローバル スコープを親として、別々のスコープで実行されているということです。

changeStatusそのため、3 番目のスクリプトで機能する理由は、var宣言がないためだと思います。したがって、他の構成がない場合、これは、3 つのスクリプト間で共有される最上位 (グローバル) スコープの変数として定義されます。

私の推測では、ローカル変数を示すキーワードで宣言されているため、hmTCResult機能しないということです。varすべてのスクリプトが最上位スコープで実行されている場合、これによりグローバル オブジェクトに変数が定義されます。ただし、各スクリプトが独自のスコープで実行される場合、スクリプト 1 のスコープでのみ変数が定義されます。スクリプト 2 のスコープでは問題は発生しません。スクリプト 2 のコードはスクリプト 3 まで誰も実行していないためです。実行します。

于 2012-11-21T22:18:33.233 に答える