2012-07-31 33 views
1

是否有某種方法可以在javascript中進行以下工作?JavaScript將對象展開爲參數

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

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

orders.forEach(makeCoffee); 
+0

他們最簡單的方法是讓'makeCoffee'接受帶有參數的單個對象。由於對象屬性是無序的,因此按正確順序傳遞屬性的唯一方法是解析函數簽名並提取參數名稱。我認爲這不值得。 – 2012-07-31 09:16:02

+0

@FelixKling這正是我想要避免的 – Manav 2012-07-31 09:16:52

+0

但它確實更加靈活和相對常見,爲什麼你要避免它? – 2012-07-31 09:17:40

回答

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。特別要注意的是,在表示字符串中使用和放置空格,行結束符和分號是依賴於實現的。

+0

太棒了!和無法使用的:) - 我會接受這個(如果沒有更好的出現),因爲它表明這樣的事情可以完成,而不是因爲它應該完成。 – Manav 2012-07-31 09:43:08

0

我可以想出到目前爲止最好的是:

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

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

優點:

  • 作品

缺點(IMO):

  • 它在順序和makeCoffee之間引入了不必要的耦合(有點像組合vs繼承的東西是如何平移的)。
  • 我們失去了makeCoffee功能的明晰宣佈其輸入
+0

回答你自己的問題壞習慣,你可以在你的問題我的朋友添加此代碼。 – yogi 2012-07-31 09:16:09

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

缺點:

  • 不漂亮
+0

如果我溝通不暢,我很抱歉。這不是我想問的問題(我真的不應該回答我自己的問題 - 它可能正在討論切線)。你的解決方案是通過使用'coffeeDefinition'明確使用'this'對象來實現隱式綁定(這是一個有價值的目標)。我的實際問題是如果某種「自動爆炸」是可能的。 – Manav 2012-07-31 09:30:48

+0

它不是,它不應該。 'orders'中的n項和'mekaCoffee()'函數**是**鏈接的 - 一個沒有其他用處是無用的 – 2012-07-31 09:39:07