javascript - 是否可以在不更改上下文的情况下调用 function.apply?

标签 javascript node.js function

在一些 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);
}

编辑:添加关于我的具体问题的更多细节。我正在创建一个客户端类,其中包含一个套接字(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/

相关文章:

node.js - 带有Node.js的Elasticsearch js:如何从多个索引返回聚合结果?

node.js - 安装nodetime时编译出错

function - Lisp 函数的返回参数

arrays - SSRS Reporting Services - 字符串中的粗体字

javascript - 使用 Javascript 获取两个日期之间的天数

javascript - Facebook Canvas : Refused to display app in a frame because it set 'X-Frame-Options' to 'DENY'

javascript - 我的代码中 request.end 的监听器有什么问题

python - publish() 至少需要 3 个参数(给定 3 个)

javascript - 如何在javascript中获取gridview文本框控件ID?

javascript - 顶级等待不适用于 Parcel