Kitson
Kitson

Reputation: 1678

JavaScript Function arguments

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

Answers (4)

MooGoo
MooGoo

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

Ruan Mendes
Ruan Mendes

Reputation: 92274

Can;t you just make the body of your functions work with the arguments property?

http://jsfiddle.net/9XcEb/

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

Felix Kling
Felix Kling

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

ChaosPandion
ChaosPandion

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

Related Questions