Reputation: 1678
I am trying to create a function that deserialises a JSON object and creates some functions, but I want to be able to specify a variable set of arguments.
For example, in JSON I want to specify something like:
{
"handler" :
{
"args" : ["evt","value"],
"content" : "console.log(value);"
}
}
And when I parse the object, I will do something like:
var myFunction = new Function(handler.args,handler.content);
But the challenge is that each argument is supposed to be a n strings followed by the content of the function as the last argument. Is there any easy way of specifying n number of arguments in a new Function()
?
Upvotes: 2
Views: 1285
Reputation: 48230
According to MDN
Parameters
arg1, arg2, ... argN
Names to be used by the function as formal argument names. Each must be a string that corresponds to a valid JavaScript identifier or a list of such strings separated with a comma; for example "x", "theValue", or "a,b".
So the arguments list can either be one or more strings seperated by commas, or just one string with each identifier in it seperated by commas.
Also since
['evt', 'value'].toString() == 'evt,value'
Simply passing your handler.args
array as the first argument to the new Function
constructor should work exactly as you want it to
new Function(handler.args, handler.content);
Internally, new Function
casts every argument to a string if it is not already one. So conceivably something like this would also work
new Function({ toString: function() { return 'a,b,c' } }, 'return a+b+c');
Not that I'm suggesting you do anything silly like that.
This works in every browser I've tried including IE
Upvotes: 1
Reputation: 92274
Can;t you just make the body of your functions work with the arguments property?
var add = new Function(
"var total=0;"+
"for (var i=0; i < arguments.length; i++) {"+
"total+=arguments[i]"+
"};"+
" return total"
);
alert(add(3,4,5,6));
Upvotes: 0
Reputation: 816312
To solve the technically issue: You can use apply
[docs].
handler.args.push(handler.content);
var myFunction = Function.apply(null, handler.args);
However the question is why you are doing something like this? What is the context? Spontaneously I would say you should consider another solution for whatever problem you are trying to solve ;)
Upvotes: 5
Reputation: 78262
I think the simplest route would be to combine the 2 properties. Then use apply
to construct the function.
var x = {
"handler" :
{
"constructorArgs" : [
"evt",
"value",
"alert(value);"
]
}
};
var f = Function.apply(undefined, x.handler.constructorArgs);
f(1, 2);
To keep it similar you can use Array.prototype.concat
.
var x = {
"handler" :
{
args: [ "evt", "value" ],
content : "alert(value);"
}
};
var f = Function.apply(undefined, x.handler.args.concat(x.handler.content));
f(1, 2);
Upvotes: 1