Reputation: 28364
Let's say I have an object that looks like this:
{
'apple': 'nice',
'banana': 'decent',
'cherry': 'yuck',
}
and I have these two methods:
function eatItems(cherry, apple) { }
function throwItem(banana) { }
My two questions:
Is it possible for me to invoke eatItem and send the arguments in the correct order? Maybe something like:
eatItems.call(this, {'cherry': cherry, 'apple': apple});
What if I don't know what arguments eatItems receives, can I dynamically look up the names of the arguments for a function so I can know the order that I need to throw them in?
Upvotes: 0
Views: 57
Reputation: 22627
There's a way, indeed, and it involves calling toString
on a function:
var source = eatItems.toString();
// => "function eatItems(cherry, apple) { }"
The next step is to parse the string you've got to get the names of the arguments:
var args = source.substring(source.indexOf("(") + 1, source.indexOf(")")),
argNames = /\S/.test(args) ? args.split(/\s*,\s*/) : [];
A few caveats:
And, overall, this solution is more like an exercise. I wouldn't recommend taking this pattern in Javascript. Don't forget that some functions handle a variable number of arguments, and you won't find them listed in their definition. Rethink your code, and find a better way.
Upvotes: 2
Reputation: 94101
If I understand correctly you want extract the argument names from the function, and inject data from an object based on those names. This can be accomplished by converting the function to a string, extracting the arguments, and applying the function with those arguments:
function inject(data, f) {
var args = f.toString()
.match(/function\s*?\((.+?)\)/)
.pop()
.split(',')
.map(function(a){return data[a.trim()]})
return function() {
return f.apply(this, args)
}
}
var data = {
apple: 'nice',
banana: 'decent',
cherry: 'yuck',
}
var eat = inject(data, function(cherry, apple) {
console.log(cherry, apple)
})
eat() //=> yuck, nice
The obvious problem with this approach is that it is highly dependent on the variable names, so when you minify your code, the variables will get mangled and the function will stop working. This is a known problem in AngularJS, which uses something similar for their dependency injection.
This is often an XY problem, or an anti-pattern at the very least.
Upvotes: 1