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
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)
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?
(As answered by @Nina Scholz in the comments, this is because ... requires its argument to have Symbol.iterator, which is not defined for objects).
How to do the same in ES6?
There are no named arguments in JS, only positional ones. So the answer is: you can not.
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);
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);
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.
You need to wrap your args in curly braces, and again in the argument list for the function.
function foo({a, b}) {
console.log(a - b)
}
let args = {b: 7, a: 10}
foo({...args})
来源:https://stackoverflow.com/questions/45735576/parameter-destructuring-equivalent-of-pythons-double-splat