Javascript将对象分解为参数

时间:2012-07-31 09:13:32

标签: javascript foreach arguments exploded

有没有办法在javascript中进行以下工作?

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

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

orders.forEach(makeCoffee);

3 个答案:

答案 0 :(得分:1)

正如我在评论中所说,在func.toString()返回函数的源代码的浏览器中,您可以解析签名并提取参数名称:

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

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

由于JavaScript不提供任何反射API,这可能是唯一的方法。


如果你没有明确说明你的代码支持哪些浏览器,这可能不起作用(我不知道IE为func.toString返回什么)。我仍然建议传递一个对象作为参数。


†:函数的确切表示依赖于实现。以下是规范中的相应描述:

  

返回函数的依赖于实现的表示。该表示具有FunctionDeclaration的语法。请特别注意,表示字符串中的空格,行终止符和分号的使用和放置取决于实现。

答案 1 :(得分:0)

我能想到的最好的是:

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

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

优点:

  • 作品

缺点(IMO):

  • 它引入了订单和makeCoffee之间不必要的耦合(有点像组合与继承事物如何淘汰)。
  • 我们失去了声明其输入的makeCoffee函数的显式性

答案 2 :(得分:0)

我推荐这个:

//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)})

的优点:

  • 工作且很健壮
  • 仅介绍必要的耦合
  • 可扩展至例如"decaffeinated":false

缺点:

  • 不漂亮