参数解构(相当于python' s-splat)

时间:2017-08-17 12:48:33

标签: javascript ecmascript-6 destructuring double-splat

在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)




NB:我正在寻找一种不会改变foo签名的解决方案,因为我希望它能以任何一种方式使用(有和没有)解构)。所以以下内容应该有效:

foo(<magic>args);

foo(123, 456);

奖金问题:为什么错误消息&#34; undefined不是函数&#34;?究竟什么是未定义的?

(正如@Nina Scholz在评论中所回答的那样,这是因为...要求其参数为Symbol.iterator,而没有为对象定义。

2 个答案:

答案 0 :(得分:3)

  

如何在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);

好的 - 好吧,只是为了论证:可以编写一个函数来提取foo的参数并按要求的顺序产生args的属性。

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));

我不敢在制作中使用它。

答案 1 :(得分:1)

您需要将args括在大括号中,并再次在函数的参数列表中。

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

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

foo({...args})