Rhino:原型链不适用于宿主对象?

发布于 2024-09-29 11:30:13 字数 1138 浏览 4 评论 0原文

在子级上调用父级中定义的方法(其中父级是主机对象)会给出 EcmaError: method called on incompile object(在不兼容的对象上调用的方法)。

Java 中定义的主机对象:

public class HostObject extends ScriptableObject {            

    public HostObject() {}

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

    public void jsFunction_sayHi() { 
        System.out.println("Hi!");
    }
}

测试脚本 #1 在 Rhino 中运行:

var foo = new HostObject();
foo.sayHi();

工作正常。

测试脚本#2:

function Bar() {}
Bar.prototype = new HostObject();
var bar = new Bar();
bar.sayHi();

抛出异常:

org.mozilla.javascript.EcmaError:TypeError:在不兼容的对象上调用方法“sayHi”。

找到了解决此问题的方法(有点......) - 通过使用定义方法的替代形式 - 带参数的静态方法(Context cx、Scriptable thisObj、Object[] args、FunObj),然后每当我需要访问成员时显式使用原型:

HostObject ho = (HostObject)thisObj.getPrototype();

事情是有一些情况 sayHi() 在原始对象上调用,然后 getPrototype() 引用 Javascript 对象,因此我需要执行额外的检查才能在这两种情况下都能正常工作。我本以为通过原型链接,原始示例应该可以正常工作。这可能是一个错误吗?或者我做错了什么?

我使用的是Rhino 1.7R2。

Invoking on a child a method defined in parent, where parent is a host object, gives EcmaError: method called on incompatible object.

Host object defined in Java:

public class HostObject extends ScriptableObject {            

    public HostObject() {}

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

    public void jsFunction_sayHi() { 
        System.out.println("Hi!");
    }
}

Test script #1 run in Rhino:

var foo = new HostObject();
foo.sayHi();

Works fine.

Test script #2:

function Bar() {}
Bar.prototype = new HostObject();
var bar = new Bar();
bar.sayHi();

Throws an exception:

org.mozilla.javascript.EcmaError: TypeError: Method "sayHi" called on incompatible object.

Found a way around this issue (kind of...) - by using an alternative form of defining a method - a static method with parameters (Context cx, Scriptable thisObj, Object[] args, Function funObj) and then explicitly using the prototype whenever I need to access members:

HostObject ho = (HostObject)thisObj.getPrototype();

Thing is there are situations when sayHi() is invoked on the original object and then getPrototype() refers to Javascript Object, so I would need to perform an extra check to make this work in both cases. I would've thought that with prototype chaining the original example should work just fine. Is that a possible bug here? Or am I doing something wrong?

I'm using Rhino 1.7R2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

森末i 2024-10-06 11:30:13

而不是使用:

HostObject ho = (HostObject)thisObj.getPrototype();

使用类似:

Scriptable obj = thisObj;
while(obj != null && !(obj instanceof HostObject)) {
    obj = obj.getPrototype();
}
HostObject ho = (HostObject)ho;

这将在原型链中找到正确的原型。

Instead of using:

HostObject ho = (HostObject)thisObj.getPrototype();

use something like:

Scriptable obj = thisObj;
while(obj != null && !(obj instanceof HostObject)) {
    obj = obj.getPrototype();
}
HostObject ho = (HostObject)ho;

This will find the right prototype in the chain of prototypes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文