javascript - 在 Rhino JS 上下文中动态声明函数

标签 javascript java rhino

我目前正在尝试在我的 Rhino JavaScript 上下文中动态声明函数。我已经达到了可以动态声明变量/属性的地步,但无法弄清楚如何将函数作为属性的值传递。这是我已经走了多远:

import java.lang.reflect.Member;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.FunctionObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

public class Main {

    public static void main(String[] args) {

        Context jsContext = Context.enter();
        try {
            Scriptable scope = jsContext.initStandardObjects();
            ScriptableObject fooObject = new ScriptableObject() {

                @Override
                public String getClassName() {
                    return "MyFoo";
                }
            };

            scope.put("foo", scope, fooObject);
            fooObject.putProperty(fooObject, "oneProperty", "This is the value of oneProperty");

            Member myFunction = /* What goes here? */ null;
            fooObject.putProperty(fooObject, "doStuff", new FunctionObject("doStuff", myFunction, fooObject));

            Object resultProp = jsContext.evaluateString(scope, "foo.oneProperty", "<cmd>", 1, null);
            Object resultFunc = jsContext.evaluateString(scope, "foo.doStuff()", "<cmd>", 2, null);

            System.out.println("Property value: " + Context.toString(resultProp));
            System.out.println("Function value: " + Context.toString(resultFunc));
        }
        finally {
            jsContext.exit();
        }
    }

}

我认为我在全局范围内正确定义了“foo”对象,并在其上设置了属性 oneProperty,但我不知道如何为该 set 方法提供一个函数。我这样做正确吗?我怎样才能为一个函数做到这一点?

更新 看起来可以创建一个新类来实现 Function 接口(interface),实现“call”方法,并忽略该接口(interface)所需的其他方法(仅返回 null)。然后可以将其提供给 putProperty 调用。这似乎有效,但是在代码中看到它很痛苦,并且通过阅读它并不清楚它的作用。我仍在寻找更好的解决方案(如果存在)。

最佳答案

你可以定义一个java类,其中包含一些你想要绑定(bind)到js的函数。然后使用class.getMethod获取Method对象来创建FunctionObject并最终将其放入js作用域。

这是一个 Kotlin 语言的演示:

class Container{
    companion object{
        @JvmStatic
        fun foo() = true
    }
}

val ctx: Context = Context.enter()
val scope = ctx.initStandardObjects()

val fMethod = Container::class.java.getMethod("foo")
val f = FunctionObject("foo", fMethod, scope)
scope.put("foo", scope, f)

ctx.evaluateString(scope, "foo()", "<cmd>", 1, null) // the result should be true

但是非静态函数会复杂很多,可以看this answer .

关于javascript - 在 Rhino JS 上下文中动态声明函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33458183/

相关文章:

c# - 从c#.net中的JS文件访问资源文件

javascript - 从当前行中选择下一个 "visible"同级

java - 如何将 setText 设置为所有 SeekBar 进度值的总和?

java - 无法使用 javascript 从 Java 中解析完整的 javascript if 语句

javascript - Narwhal和Node.js之间的差异

java - 为什么 jrunscript 不支持我的类路径?

javascript - 使用 VideoDecoder 解码 MP4 视频

javascript - 仅在 NodeJS/浏览器的开发模式下显示日志信息

java - 将 MySQL 日期转换为 Java 日期 : Android

java - 如何使用 Java 流将一组字符串转换为一组映射?