2014-10-06 5 views
1

Например, у меня есть:Expose функции члена объекта как глобальные функции

var n = { 
    abc: function() { print("abc"); }, 
    def: function() { print("def"); }, 
}; 

Есть ли способ экспортировать abc и def как глобальные функции, так что я могу назвать abc() напрямую, а не n.abc()?

Мой контекст для этого используется механизм сценариев Rhino/Nashorn, и я бы хотел ввести «глобальный» объект, который предоставляет глобальные функции.

+1

В зависимости от среды вы можете выполнить команду 'var abc = n.abc;' или 'global.abc = n.abc' или' var abc = n.abc; export {abc}; 'или' export.abc = n.abc' или несколько других вариантов. –

+0

спасибо, похоже, что глобальный - это тот, который я ищу! Мне все равно нужно найти другой способ итерации через n, чтобы перечислять все ключи - так или иначе (key in n) {...} не работает, если n вводится из Java за пределами. – Vin

ответ

2

Почему бы вам просто не использовать методы JavaScript bind, call и apply, чтобы вызвать функции-члены объекта, когда вам нужно их вызывать? Сделать их глобальными означает запах кода.

+0

спасибо, запишите звуки очень многообещающие. вызов и применение кажется излишним, поскольку целью «экспорта» было упростить написанный сценарий. Запах кода не является проблемой, поскольку открытые функции могут быть хорошо контролируемы с внешней стороны Java. – Vin

3

Ответы для Rhino и Nashorn будут разными.

Для Rhino, когда вы создаете глобальный объект с помощью Context.initStandardObjects, вы можете добавить свои свойства на стороне Java, вызвав ScriptableObject.defineProperty (см Rhino API), а затем свойства будут добавлены к этой глобальной области видимости. Если вам нужно свойство типа function, как показывает ваш пример, создайте его, используя FunctionObject API.

Для Nashorn вы можете использовать интерфейсы в основном на основе стандартных API-интерфейсов с несколькими расширениями для Nashorn. При оценке сценарий, первым использовать ScriptEngine.createBindings() создать объект Bindings, а затем использовать Bindings.put использовать eval(String/Reader,Bindings)

Если вам нужна функция собственности, то на стороне вызова Java ScriptUtils.wrap создать ScriptObjectMirror (убедитесь, что бросить его в том, что ; возвращаемый тип метода - Object), затем вызовите get([function name]), чтобы получить свойство исполняемой функции, а затем поместите его в глобальную область.

Все, что сказал, мне кажется, что это более легко обрабатывается на стороне сценария с помощью:

var abc = function() { return n.abc.apply(n,arguments); }; 

Это портативный через Rhino/Nashorn и является одна линия, которая намного меньше работы, чем что вы собираетесь делать, если хотите избежать написания этой строки.

Если вы выполняете это в глобальном масштабе, вам не нужен определитель; он будет добавлен к объекту верхнего уровня в качестве свойства. Если вы хотите быть более четко вы можете сделать что-то вроде этого:

(function() { 
    var global = this; // inner functions called without target default to global as 'this' 
    this.abc = function() { return n.abc.apply(n,arguments); }; 
})(); 

... который будет работать, если вы не начнете делать вещи, которые много любитель (как возиться с «это» значения, когда погрузка скриптов).

+0

Это то, чем я был. Но каким-то образом я попал в блок: 'Caused by: : 3 TypeError: [jdk.internal.dynalink.beans.SimpleDynamicMethod void ScriptProxy.load (String)] не имеет такой функции «apply». Похоже, что методы-члены вводимого объекта отличаются от обычных функций javascript. Знаете ли вы способ заставить инъецированную оболочку действовать как обычная функция javascript? Или преобразован? – Vin

+0

Не могли бы вы более подробно описать, что вы сделали, что привело к ошибке? –

+0

Итак, в Java, 'scriptEngine.put (« w », new ScriptProxy());', а затем eval 'this [" load "] = w.load.bind (w);' и это дало 'no такой функции ". – Vin

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

  • Нет связанных вопросов^_^