参数解构(等同于python的double-splat) [英] Parameter destructuring (equivalent of python's double-splat)

查看:78
本文介绍了参数解构(等同于python的double-splat)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In python I can pass a dict whose keys match parameters' names with the ** (double-splat) operator:

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

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

foo(**args) # prints 3

如何在ES6中执行相同的操作?这不起作用:

How to do the same in ES6? This doesn't work:

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

args = {b: 7, a: 10}

foo(...args)

注意:我正在寻找一种不涉及更改foo签名的解决方案,因为我希望以任何一种方式使用它(带或不带解构).因此,以下方法应该起作用:

NB: I'm looking for a solution that wouldn't involve changing the signature of foo because I want it to be used either way (with and without destructuring). So the following should work:

foo(<magic>args);

foo(123, 456);

奖金问题:为什么错误消息未定义不是函数"?究竟未定义在这里什么?

Bonus question: why is the error message "undefined is not a function"? What exactly is undefined here?

(正如@Nina Scholz在评论中回答的,这是因为...要求其自变量具有Symbol.iterator,这不是为对象定义的.)

(As answered by @Nina Scholz in the comments, this is because ... requires its argument to have Symbol.iterator, which is not defined for objects).

推荐答案

如何在ES6中执行相同的操作?

How to do the same in ES6?

JS中没有命名参数,只有位置参数.答案是:您不能.

There are no named arguments in JS, only positional ones. So the answer is: you can not.

您可以执行的操作是通过对象传递来模拟命名参数,如@Andy建议的那样.

What you can do is either emulate named arguments via object passing, as @Andy suggested.

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

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

foo(args);

或者您可以将args设置为数组,以便将其分解为位置参数.

Or you could make args to be an array, so you can destruct it into positional arguments.

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

let args = [10, 7];

foo(...args);

好吧,仅出于争论的目的:可以编写一个函数,该函数将按要求的顺序提取foo的参数并产生args的属性.

Okay-okay, just for the sake of the argument: it is possible to write a function that will extract parameters of foo and yield properties of args in required order.

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

虽然我不敢在生产中使用它.

I would not dare to use it in production though.

这篇关于参数解构(等同于python的double-splat)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆