Javascript explotar objeto a argumentos

Is there some way to make the following work in javascript?

var orders = [
   {milk: true, sugar: "extra"}, 
   {milk: false, sugar: "normal"}
   ];

function makeCoffee(sugar, milk) {
    console.log(sugar);
    console.log(milk);
}

orders.forEach(makeCoffee);

preguntado el 31 de julio de 12 a las 10:07

They easiest way would to make makeCoffee accept a single object with the arguments. Since object properties are unordered the only way to pass the properties in the right order is to parse the function signature and extract the parameter names. I don't think that's worth it. -

@FelixKling that is exactly what I am trying to avoid -

But it really is more flexible and relatively common to do so, why are you trying to avoid it? -

@FelixKling it works, but it litters the code i.e. function makeCoffee(dummy) {console.log(dummy.milk); console.log(dummy.sugar);}. Anyways, the question is about if or not something like this is possible - debate about their pros and cons is for another day :) -

3 Respuestas

As I said in my comment, in browsers where func.toString() returns the source of the function , you could parse the signature and extract the parameter names:

var arg_names = makeCoffee.toString()
            .match(/function[^(]*\(([^)]*)\)/)[1].split(', ');

orders.each(function(order) {
    makeCoffee.apply(null, arg_names.map(function(name) {
        return order[name];
    });
});

Since JavaScript does not provide any reflection API, this is probably the only way.


If you don't explicitly state in which browsers your code is supported, this might not work (I don't know what IE returns for func.toString). I still recommend to pass an object as argument.


†: The exact representation of the function is implementation dependent though. Here is the corresponding description from the specification:

Se devuelve una representación dependiente de la implementación de la función. Esta representación tiene la sintaxis de un FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.

Respondido 31 Jul 12, 10:07

Brilliant! and unusable :) - I'll accept this (if nothing better comes along) because it shows that something of this sort can be done, not because it should be done. - manav

The best I can come up with till now is:

function makeCoffee() {
    console.log(this.milk);
    console.log(this.sugar);
}

orders.forEach(function(x) {makeCoffee.call(x)})

Pros:

  • )

Cons (IMO):

  • it introduces unnecessary coupling between the order and makeCoffee (sort of like how the composition vs inheritance thing panned out).
  • we lose the explicitness of the makeCoffee function declaring its inputs

Respondido 31 Jul 12, 10:07

Answering your own questions bad habit, You could have added this code in your question my friend. - yogui

Recomiendo esto:

//Should go to config.js
var COFFEE_SUGAR_DEFAULT="normal";

var orders = [
   {milk: true, sugar: "extra"}, 
   {milk: false, sugar: "normal"}
   ];

function makeCoffee(coffeeDefinition) {
    if (!coffeeDefinition.sugar) coffeeDefinition.sugar=COFFEE_SUGAR_DEFAULT;
    if (!coffeeDefinition.milk) coffeeDefinition.milk=false; //might not be a real boolean
    console.log(coffeeDefinition.sugar);
    console.log(coffeeDefinition.milk);
}

orders.forEach(function(x) {makeCoffee(x)})

pros:

  • works and is robust
  • introduces just the necessary coupling
  • is expandable to e.g. "decaffeinated":false

contras:

  • not pretty

Respondido 31 Jul 12, 10:07

I am sorry if I miscommunicated. This is not what I wanted to ask (I really shouldn't have answered my own question - it is perhaps taking the discussion on a tangent). Your solution is about making the implicit binding that was achieved through using the this object explicit by using a coffeeDefinition (which is a worthy goal). My actual question is if or not some sort of "automatic exploding" is possible. - manav

It is not, and it should not. A n item in orders y mekaCoffee() función están linked - one is useless without the other - Eugen Riek

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.