0

このJavaコードを実行すると、関数の外部で変数定義の値を取得できますが、関数の内部で変数定義の値を取得できません。これらの変数値にアクセスする方法は?

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


public class JSFunctionTest {

public static void main(String args[]) {

    String code = "var name='nc',global_a = 'jill'; " + "\n"+
            "function myfunc(b) { " + "\n"+
            "var local_a = 1;" + "\n"+
            "global_a = 'jack';" + "\n"+
            " return b;" + "\n"+
            "}"; 

    Context context = Context.enter();
    context.setGeneratingDebug(true);
    context.setOptimizationLevel(-1);

    Scriptable scope = context.initStandardObjects(); 

    context.evaluateString(scope, code, "code", 1, null);
    //getting values of varables
    System.out.println("var name:"+scope.get("name", scope));
    System.out.println("var global_a:"+scope.get("global_a", scope));
    System.out.println("var local_a:"+scope.get("local_a", scope));//not found becase function wasnt run

    //calling the function.
    Object fObj = scope.get("myfunc", scope);
    if (!(fObj instanceof Function)) {
        System.out.println("myfunc is undefined or not a function.");
    } else {
        Object functionArgs[] = { "nc" };
        Function f = (Function)fObj;
        Object r = f.call(context, scope, scope, functionArgs);
        String report = "myfunc('nc') = " + Context.toString(r);

        //trying to access global and local a after calling function
        System.out.println("var global_a:"+scope.get("global_a", scope));//values is changed, because this is defined out side the function.
        System.out.println("var local_a:"+scope.get("local_a", scope));// still not found,after running the function.

        System.out.println(report);
    }

}

}

4

2 に答える 2

1

RhinoでデバッグAPIを使用してデバッガーを実装することで、これを解決することができました。

  1. 独自のデバッガークラスとdebugframeクラスを実装します。
  2. setDebugger()メソッドを使用してそれらをコンテキストにフックします
  3. DebugFrameクラスに実装しました。onEnterメソッドでスコープオブジェクトをキャッシュします。
  4. onLineChangeメソッドでは、ScriptableObject.getProperty()を使用してローカル変数を取得し、キャッシュスコープオブジェクトを渡して名前を付けることができます。
于 2012-07-25T15:29:44.253 に答える
0

ECMAScriptでは、関数は独自のスコープを作成します。グローバルスコープの外では、それが新しいものを作成する唯一の方法です。似たような例については、Rhinoのスコープとコンテキストを参照してください。

重要なのは、ECMAScriptが動的言語であるということです(特に最適化レベルがインタープリターモードに設定されている場合)。これは、通訳者が何に遭遇するかを事前に知らないことを意味します。関数のスコープは、コードが実際に実行されたときにのみ作成/評価されます。したがって、コードの一部を評価したり、実行されていないスコープ内の変数を照会したりすることはできません。

問題は、なぜ実際にそれをしたいのかということです。デバッグのために、コードにステップインしてスコープを調べることができます。それを見ることができるはずです。

于 2012-07-24T15:19:54.527 に答える