在某些Javascript代码中(特别是node.js),我需要在不更改上下文的情况下调用带有未知参数集的函数。例如:

function fn() {
    var args = Array.prototype.slice.call(arguments);
    otherFn.apply(this, args);
}

上面的问题是,当我调用apply时,我通过传递this作为第一个参数来更改上下文。我想将args传递给名为的函数,而无需更改被调用函数的上下文。我本质上是想这样做:
function fn() {
    var args = Array.prototype.slice.call(arguments);
    otherFn.apply(<otherFn's original context>, args);
}

编辑:添加有关我的特定问题的更多详细信息。我正在创建一个Client类,其中包含一个套接字(socket.io)对象以及与连接有关的其他信息。我通过客户端对象本身公开了套接字的事件监听器。
class Client
  constructor: (socket) ->
    @socket    = socket
    @avatar    = socket.handshake.avatar
    @listeners = {}

  addListener: (name, handler) ->
    @listeners[name] ||= {}
    @listeners[name][handler.clientListenerId] = wrapper = =>
      # append client object as the first argument before passing to handler
      args = Array.prototype.slice.call(arguments)
      args.unshift(this)
      handler.apply(this, args)  # <---- HANDLER'S CONTEXT IS CHANGING HERE :(

    @socket.addListener(name, wrapper)

  removeListener: (name, handler) ->
    try
      obj = @listeners[name]
      @socket.removeListener(obj[handler.clientListenerId])
      delete obj[handler.clientListenerId]

请注意,clientListenerId是一个自定义的唯一标识符属性,与the answer found here基本上相同。

最佳答案

如果我对您的理解正确,请执行以下操作:

                          changes context
                   |    n     |      y       |
accepts array    n |  func()  | func.call()  |
of arguments     y | ???????? | func.apply() |

PHP为此提供了一个函数call_user_func_array。不幸的是,在这方面缺少JavaScript。看起来您使用eval()模拟了此行为。
Function.prototype.invoke = function(args) {
    var i, code = 'this(';
    for (i=0; i<args.length; i++) {
        if (i) { code += ',' }
        code += 'args[' + i + ']';
    }
    eval(code + ');');
}

是的,我知道。没有人喜欢eval()。这是缓慢而危险的。但是,在这种情况下,您至少不必担心跨站点脚本编写,因为所有变量都包含在函数中。确实,JavaScript对此没有 native 功能真是太糟糕了,但我想我们有eval可以用于这种情况。

证明有效:
function showArgs() {
    for (x in arguments) {console.log(arguments[x]);}
}

showArgs.invoke(['foo',/bar/g]);
showArgs.invoke([window,[1,2,3]]);

Firefox控制台输出:
--
[12:31:05.778] "foo"
[12:31:05.778] [object RegExp]
[12:31:05.778] [object Window]
[12:31:05.778] [object Array]

关于javascript - 是否可以在不更改上下文的情况下调用function.apply?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12336044/

10-12 12:19
查看更多