2017-08-17 49 views
2

在Python中,我可以通過一個字典,它的鍵匹配參數的名字與**(雙圖示)操作:參數解構(Python的雙圖示的當量)

def foo(a, b): 
    print (a - b) 

args = {'b': 7, 'a': 10} 

foo(**args) # prints 3 

如何做ES6相同?這不起作用:

function foo(a, b) { 
 
    console.log(a - b) 
 
} 
 

 
args = {b: 7, a: 10} 
 

 
foo(...args)

注:我正在尋找,因爲我希望它可以使用任何一種方式,不會涉及改變的foo簽名的解決方案(有和沒有解構)。所以下面應該工作:

foo(<magic>args); 

foo(123, 456); 

獎金的問題:爲什麼錯誤消息「undefined不是一個函數」?究竟什麼是未定義的?

(由@Nina Scholz在評論中回答,這是因爲...要求其參數具有Symbol.iterator,這是沒有爲對象定義的)。

+2

獎勵問題,對於對象,沒有符號迭代器。 –

回答

2

如何做ES6一樣嗎?

JS中沒有命名參數,只有位置參數。所以答案是:你不能。

你可以做的是模擬命名參數通過對象傳遞,@Andy建議。

function foo({ a, b }) { 
    console.log(a - b); 
} 

let args = { b: 7, a: 10 }; 

foo(args); 

或者你可以讓args是一個數組,這樣你就可以破壞它變成位置參數。

function foo(a, b) { 
    console.log(a - b); 
} 

let args = [10, 7]; 

foo(...args); 

好-沒關係,只爲參數的緣故:它是可能寫一個函數,將提取的在要求的順序的argsfoo及產量性狀參數。

function * yolo(args, fn) { 
    const names = fn.toString().match(/\(.+\)/)[0] 
        .slice(1, -1).split(',') 
        .map(x => x.trim()); 

    while (names.length) { 
     yield args[names.shift()]; 
    } 
} 

function foo(a, b) { 
    console.log(a - b); 
} 

const args = { b: 7, a: 10 }; 

foo(...yolo(args, foo)); 

我不敢在生產中使用它。

+0

謝謝,這是我害怕的。 ;( – georg

+0

回覆:生產-IIRC,Angular基於這種方法嚴重(或曾經是)。 – georg

1

你需要用大括號將你的args包裝起來,再次包含在函數的參數列表中。

function foo({a, b}) { 
    console.log(a - b) 
} 

let args = {b: 7, a: 10} 

foo({...args}) 
+1

'{... args}'基本上是'args'。 –

+1

'{... args}'是ES7,對吧? – georg

+0

帶有一個變量的'{... variable}'只是對象的淺表副本。它適用於babel。 –