Reputation: 48720
I'm currently using Function.apply to call a function with a dynamic number of arguments, but I do not have access to the original context, and have no desire to set the context myself. What I would like, is to be able to call a function with a variable number of arguments, keeping the original context.
Perhaps some code should show you what I'm trying to do:
function MulticastDelegate() {
var handlers = [];
this.event = {
subscribe: function(handler) {
if (typeof(handler) === 'function') {
handlers.push(handler);
}
},
unsubscribe: function(handler) {
if (typeof(handler) === 'function') {
handlers.splice(handlers.indexOf(handler),1);
}
}
}
this.execute = function() {
var args = Array.prototype.slice.call(arguments);
for (var handler in handlers) {
// call this with the original context of the handler
handlers[handler].apply(null, args);
}
}
}
Essentially, I want the behaviour of apply
- the ability to pass an array of arguments - without the behaviour of call
- changing the context under which a function executes.
Upvotes: 6
Views: 498
Reputation: 8562
Could it be, that .bind
would solve the case?
http://documentcloud.github.com/underscore/#bind
In this case, you get a function 'binded' to the original context
Upvotes: 0
Reputation: 19270
There is no such thing as “the original context” of a function. You would have to do something like this:
subscribe: function(handler, context) {
if (typeof(handler) === 'function') {
handlers.push([handler, context]);
}
},
And then, of course,
handlers[handler][0].apply(handlers[handler][1], args);
Alternatively (this is what I would do), leave it to the caller to make sure the handler has the right context. For example, instead of delegate.subscribe(this.foo)
, say
var self = this
delegate.subscribe(function () { self.foo() })
Or, using Function.prototype.bind,
delegate.subscribe(this.foo.bind(this))
Upvotes: 5