例如我有:
var n = {
abc: function() { print("abc"); },
def: function() { print("def"); },
};
有没有办法导出abc
和def
作为全局函数,以便我可以abc()
直接调用而不是调用n.abc()
?
我的上下文是使用 Rhino/Nashorn 脚本引擎,我想注入一个提供全局函数的“全局”对象。
例如我有:
var n = {
abc: function() { print("abc"); },
def: function() { print("def"); },
};
有没有办法导出abc
和def
作为全局函数,以便我可以abc()
直接调用而不是调用n.abc()
?
我的上下文是使用 Rhino/Nashorn 脚本引擎,我想注入一个提供全局函数的“全局”对象。
Rhino 和 Nashorn 的答案会有所不同。
对于 Rhino,当您使用 创建全局对象时Context.initStandardObjects
,您可以通过调用ScriptableObject.defineProperty
(请参阅Rhino API)在 Java 端添加属性,然后属性将添加到该全局范围。如果您需要function
示例所示类型的属性,请使用FunctionObject API创建它。
对于 Nashorn,您可以使用主要基于标准javax.script
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); };
})();
...除非您开始做一些更花哨的事情(例如在加载脚本时弄乱“this”值),否则这将起作用。
当你需要调用对象的成员函数时,为什么不直接使用 JavaScript 的bind
,call
和apply
方法来调用它们呢?使它们全局化表明代码异味。