将对象的成员函数公开为全局函数

时间:2014-10-06 04:11:15

标签: javascript rhino nashorn

例如我有:

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

有没有办法将abcdef导出为全局函数,以便我可以直接调用abc()而不是n.abc()

我的上下文是使用Rhino / Nashorn脚本引擎,我想注入一个提供全局函数的“全局”对象。

2 个答案:

答案 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的bindcallapply方法来调用对象的成员函数?使它们成为全球性表明代码味道。