【问题标题】:Parameter destructuring (equivalent of python's double-splat)参数解构(相当于python的double-splat)
【发布时间】:2018-01-25 21:30:45
【问题描述】:

在 python 中,我可以通过 ** (double-splat) 运算符传递其键与参数名称匹配的字典:

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

额外问题:为什么错误消息“未定义不是函数”?这里到底是什么未定义?

(正如 @Nina Scholz 在 cmets 中回答的那样,这是因为 ... 要求其参数具有 Symbol.iterator,这不是为对象定义的)。

【问题讨论】:

  • 额外问题,对于对象,没有符号迭代器。

标签: javascript ecmascript-6 destructuring double-splat


【解决方案1】:

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

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

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

foo({...args})

【讨论】:

  • {...args} 基本上是args
  • { ...variable } 带有一个变量只会生成对象的浅表副本。它适用于 babel。
【解决方案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);

好的,好的,只是为了论证:可以编写一个函数来提取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));

但我不敢在生产中使用它。

【讨论】:

  • 谢谢,这就是我害怕的。 ;(
猜你喜欢
  • 2017-12-14
  • 2013-06-27
  • 2013-11-13
  • 2014-10-01
  • 1970-01-01
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
相关资源
最近更新 更多