2017-08-17 60 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。 –