2

例如我有:

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

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

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

4

2 回答 2

3

Rhino 和 Nashorn 的答案会有所不同。

对于 Rhino,当您使用 创建全局对象时Context.initStandardObjects,您可以通过调用ScriptableObject.defineProperty(请参阅Rhino API)在 Java 端添加属性,然后属性将添加到该全局范围。如果您需要function示例所示类型的属性,请使用FunctionObject API创建它。

对于 Nashorn,您可以使用主要基于标准javax.scriptAPI 的接口,以及一些 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”值),否则这将起作用。

于 2014-10-06T08:57:04.080 回答
2

当你需要调用对象的成员函数时,为什么不直接使用 JavaScript 的bind,callapply方法来调用它们呢?使它们全局化表明代码异味。

于 2014-10-06T04:18:40.447 回答