Reputation: 6310
I'm trying to find the best way to pass an array of arguments to a function, but without altering (or addressing) the execution context.
I have this:
some_args = ["world"];
in.some.namespace.hello.apply(this, some_args);
Unfortunately this changes hello
s execution context to the global object.
What's the slickest way of calling hello
with in.some.namespace
being the execution context?
Writing
in.some.namespace.hello.apply(in.some.namespace, some_args]
looks verbose and errorprone.
Upvotes: 3
Views: 73
Reputation: 3627
If the question is simply to write the line of code as short as possible, consider caching in a variable what's redundant (it's also better for perfs as it reduces the number of lookups):
var n = in.some.namespace;
n.hello.apply(n, some_args);
Upvotes: 0
Reputation: 1075219
Writing
in.some.namespace.hello.apply(in.some.namespace.hello, some_args]
looks verbose and errorprone.
(In the below I've changed in.
to n.
because you can't declare a variable called in
and I wanted to provide some live examples.)
Three options, none of them really exciting: ;-)
Use with
, despite its bad rep and incompatibility with strict mode
Write yourself a utility function
Use a disposable variable and don't mind some really funky-looking syntax
with
:with (n.some) {
namespace.hello.apply(namespace, some_args);
}
Slightly less repetition, though there's still some, and you have to use with
, which is disallowed in strict mode.
Example utility function:
function callWith(obj, name, args) {
return obj[name].apply(obj, args);
}
var n = {
some: {
namespace: {
hello: function(a, b, c) {
alert(this.name + " says " + [a, b, c].join(", "));
},
name: "namespace"
}
}
};
callWith(n.some.namespace, "hello", [1, 2, 3]);
(Be careful doing that if you use a minifier that renames methods, as it probably won't update the string.)
I want to be clear that I'm not recommending this, just flagging it up as an option: If you have a variable you keep lying around for this purpose, you can do this:
(o = n.some.namespace, o.hello.apply(o, [1, 2, 3]));
E.g.:
var o;
var n = {
some: {
namespace: {
hello: function(a, b, c) {
alert(this.name + " says " + [a, b, c].join(", "));
},
name: "namespace"
}
}
};
(o = n.some.namespace, o.hello.apply(o, [1, 2, 3]));
Arguably that's an abusage of the comma operator. At the very least. :-)
Upvotes: 3
Reputation: 3627
If you are looking for a way to create a function delegate:
function $createDelegate(instance, method)
{
return function (someArgs) { return method.apply(instance, someArgs); }
}
Usage:
var delegate = $createDelegate(in.some.namespace, in.some.namespace.hello);
...
delegate(someArgs);
Which, for instance, is a very useful way to pass callbacks to an event Handler without loosing your context.
Upvotes: 0