2013-07-11 75 views
3

我在使用Java對象作爲JavaScript原型時遇到了困難。這說明了我的問題:作爲Rhino原型的Java對象

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

在我看來,這絕不應該發生:原型上可訪問的任何函數屬性都必須可以訪問對象本身。

我的目標是爲包裝的Java對象添加更多的函數屬性。是否至少有一個解決方法來獲得Rhino的預期效果?約束是必須在JavaScript端添加屬性。

我的犀牛是1.7R4。

+0

爲什麼不只是'var test = new java.util.ArrayList();'? – Andremoniy

+0

@Andremoniy我正在尋找一種將更多屬性添加到Java對象的方法。 –

回答

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 = {}; 

這聽起來像一個犀牛的錯誤給我,或者至少提高一個點。

+0

'新的NativeObject()'與JS中的'{}'不完全相同。缺少的是它的默認原型「對象」。考慮這個:'NativeObject prototype = new NativeObject(); prototype.setPrototype(ScriptableObject.getObjectPrototype(範圍)); sret.setPrototype(prototype);'不同之處在於:沒有原型的NativeObject沒有默認的toString()實現。所以試圖在某處打印會導致錯誤。 –