2013-07-11 3 views
3

У меня возникли трудности с использованием объектов Java в качестве прототипов JavaScript. Это иллюстрирует мою проблему:Java Object как прототип в Rhino

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

Мне кажется, что это никогда не должно произойти: любая функция доступна свойство на прототипе должны быть доступны на самом объекте.

Моя цель - добавить дополнительные свойства функций к обернутому объекту Java. Есть ли хотя бы обходной путь для получения желаемого эффекта с Rhino? Ограничение состоит в том, что добавление свойств должно выполняться со стороны JavaScript.

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

Это звучит как ошибка Rhino мне, или, по крайней мере, точка для улучшения.

+0

'new NativeObject()' не совсем то же самое, что и '{}' в JS. Отсутствует его прототип по умолчанию 'Object'. Рассмотрим это: 'NativeObject prototype = new NativeObject(); prototype.setPrototype (ScriptableObject.getObjectPrototype (масштаб)); sret.setPrototype (prototype); 'Разница, например: NativeObject без прототипа не имеет реализации по умолчанию toString(). Поэтому попытка распечатать его где-нибудь приведет к ошибке. –

Смежные вопросы