4
var foo = function(a, b, c) {

  console.log(a);
  console.log(b);
  console.log(c.id);

};

//this works obviously
foo("a man", "b man", {id: "c.id man"}); 

var par = {
  a: "a val",
  b: "b cal",
  c: {
    id: "c.id val"
  }
};


//can I make this work automatically?
foo(par);

Question is in code sample.

Can I automatically "unwrap" the par object to use the properties to fill in the function parameters?

Is there some kind of foo(par.unwrap()) in javascript?

http://plnkr.co/edit/Y5M3qq7ROfaGGXrU21G5?p=preview

Thomas Stock
  • 10,927
  • 14
  • 62
  • 79
  • Not automagically, but you can check the type of arguments and do what's necessary. `arguments` is dynamic. – elclanrs Nov 18 '14 at 09:20
  • No, you cannot. Not without [accessing the parameter names of the function](http://stackoverflow.com/q/1007981/1048572) – Bergi Nov 18 '14 at 09:27
  • 1
    I made an answer for the question we see. But maybe it's a XY problem and you forgot to tell us why you want that ? – Denys Séguret Nov 18 '14 at 09:39

6 Answers6

4

You can, but given that object properties are unordered it's a little hacky. The solution is to parse the function as a string to get the name of the parameters.

Here's a utility function :

function callunwrap(f,o){
    f.apply(null, (f.toString().match(/\([^\)]*\)/)[0].match(/\w+/g)||[]).map(function(name){
        return o[name];
    }));
}

Usage example

var foo = function(a, b, c) {
  console.log(a);
  console.log(b);
  console.log(c.id);
};

var par = {
  a: "a val",
  b: "b cal",
  c: {
    id: "c.id val"
  }
};


callunwrap(foo, par);

Now, as you see, callunwrap does a lot of things, I wouldn't recommend to use such a hacky thing in a real program. The usual non hacky solution is to have your function explicitly read the arguments :

var foo = function(o) {
  console.log(o.a);
  console.log(o.b);
  console.log(o.c.id);
};
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • thanks, very interesting. I used the object-as-array solution because it fits my scenario best, but your answer answers my question best. – Thomas Stock Nov 18 '14 at 10:02
1

You can try

var parWorking = ["a val", "b cal", {
    id: "c.id val"
  }
];
foo.apply(this, parWorking);
Max
  • 1,090
  • 10
  • 23
0

JavaScript argument names can be arbitrary and irrelevant, so it doesn't attach too much importance to them. In other words, you cannot set specific arguments based on name. More important are their indexes.

If you create an array out of the object's values, you can use foo.apply() to pass them in:

foo.apply(null /* the context */, parAsArray);
Community
  • 1
  • 1
Scimonster
  • 32,893
  • 9
  • 77
  • 89
0

Pretty easy to do it yourself?

var args = [];
for(var p in par){
    args.push(par[p]);
}
console.log(args); // ["a val", "b cal", Object { id="c.id val"}]

foo.apply(this, args);

http://jsfiddle.net/9fzg3ehu/

filur
  • 2,116
  • 6
  • 24
  • 47
0

You can create upwrap() method for that Object.

var foo = function(a,b,c) {

  console.log(a);
  console.log(b);
  console.log(c.id);

};

 var par = {
  a: "a val",
  b: "b cal",
  c: {
    id: "c.id val"
  },
  unwrap:function(){
    var valueArray=[];
    for(key in this){
      if(typeof this[key]!=="function"){
        valueArray.push(this[key]);
      }

    }
    return valueArray;
  }
};



foo("a man", "b man", {id: "c.id man"}); 
foo.apply(null,par.unwrap())

Updated plunker

Shoaib Chikate
  • 8,665
  • 12
  • 47
  • 70
0

You can do that if you use the ES-6 arguments deconstruction. The way to do it would be to define the function like

function foo({a, b, c}) {
  //here just use a, b, c as you want;
}

var par = {
  a: "a val",
  b: "b cal",
  c : {
  id: "c.id val"
 }
};
foo(par);

You can see the demo here

Hrishi
  • 7,110
  • 5
  • 27
  • 26