3

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

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

在我看来,这永远不会发生:原型上可访问的任何函数属性都必须在对象本身上可访问。

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

我的犀牛是1.7R4。

4

1 回答 1

1

正如这里所解释的,解决方法是将包装的 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 = {};

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

于 2013-07-11T13:55:30.977 回答