例如我有:
var n = {
abc: function() { print("abc"); },
def: function() { print("def"); },
};
有没有办法将abc
和def
导出为全局函数,以便我可以直接调用abc()
而不是n.abc()
?
我的上下文是使用Rhino / Nashorn脚本引擎,我想注入一个提供全局函数的“全局”对象。
答案 0 :(得分:3)
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); };
})();
......除非你开始做的事情比较漂亮(比如在加载脚本时弄乱这个'值),否则它会起作用。
答案 1 :(得分:2)
为什么不在需要调用对象时使用JavaScript的bind
,call
和apply
方法来调用对象的成员函数?使它们成为全球性表明代码味道。