Java对象作为Rhino的原型

时间:2013-07-11 11:32:34

标签: java javascript rhino

我在使用Java对象作为JavaScript原型时遇到了困难。这说明了我的问题:

var test = {};
test.prototype = new java.util.ArrayList();
test.prototype.add(1); // works
test.add(1);           // fails

在我看来,这绝不应该发生:原型上可访问的任何函数属性必须可以在对象本身上访问。

我的目标是为包装的Java对象添加更多函数属性。是否至少有一种解决方法可以获得Rhino所需的效果?约束是必须在JavaScript端添加属性。

我的犀牛是1.7R4。

1 个答案:

答案 0 :(得分:1)

正如here所解释的,解决方法是将包装的Java对象的原型设置为new NativeObject()。请注意,在链接的线程中,没有任何权威机构确认这实际上是正确的事情,因此可能只是发生为您的用例工作并打破其他用户。

无论如何,在Java端设置原型的最佳位置是自定义wrapFactory

cx.setWrapFactory(new WrapFactory() {
  @Override public Object wrap(Context cx, Scriptable scope, Object obj, Class<?> staticType) {
    final Object ret = super.wrap(cx, scope, obj, staticType);
    if (ret instanceof Scriptable) {
      final Scriptable sret = (Scriptable) ret;
      if (sret.getPrototype() == null) sret.setPrototype(new NativeObject());
    }
    return ret;
  }
});

并且在JavaScript方面现在可以使用:

var test = new java.util.ArrayList();
test.x = 'a';

因此,与您发布的尝试相比,您需要反转对象和原型的角色。

一个有趣的事情:现在你也可以在JavaScript端自由设置原型:

test.prototype = {};

这对我来说听起来像是一个犀牛的错误,或者至少有一点需要改进。