【发布时间】:2012-09-09 02:22:47
【问题描述】:
在一些 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 基本相同。
【问题讨论】:
-
您是在问如何获取对全局上下文的引用?
-
您是否尝试过将第一个参数留空?只要它不是必需的参数,就应该有效。
-
听起来你需要在将参数应用到绑定函数之前使用
Function.prototype.bind。 -
@Matt:函数永远不属于对象。如果您只有一个函数引用,那么调用该函数会将
this设置为全局对象,除非它被.bind绑定到另一个值。如果是这样,那么将任何值作为this传递都不会改变它。如果函数是“对象的方法”,则还需要引用该对象。 -
@Matt 我认为您将无法从您的 Client 类中执行此操作。在调用
addListener时,对处理程序上下文的引用已经丢失。 调用addListener的代码可以在调用之前对相应的对象执行bind函数。那应该可以正常工作。但是一旦上下文丢失,它就完全消失了。对不起。
标签: javascript node.js function