如何使用Rhino在函数内定义变量值?

时间:2012-07-24 14:49:22

标签: rhino

当我运行这个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);
    }

}

}

2 个答案:

答案 0 :(得分:1)

通过在Rhino中使用调试API实现调试器,我能够解决这个问题。

  1. 实现自己的调试器和调试帧类。
  2. 使用setDebugger()方法将它们连接到您的上下文
  3. 在DebugFrame类中,我已经实现了。将范围对象缓存在onEnter方法中。
  4. 在onLineChange方法中,您可以使用ScriptableObject.getProperty()传递缓存范围对象并给出名称来获取局部变量

答案 1 :(得分:0)

在ECMAScript中,函数创建自己的范围。在全球范围之外,它是创建新的范围的唯一方法。有关与您类似的示例,请参阅Rhino Scopes and Contexts

问题是ECMAScript是一种动态语言(特别是当优化级别设置为解释模式时)。这意味着翻译人员事先并不知道会遇到什么。仅在实际执行代码时才创建/评估函数的作用域。因此,您无法评估一段代码并查询未执行的作用域内的变量。

问题是你为什么要在实践中这样做?对于调试,您可以进入代码并检查范围,您应该能够看到它。