[英]Can I bypass optional parameters and still set a rest parameter in Javascript?
I have a function with a required parameter (A), some optional parameters (B,C) and a rest parameter (Z) 我有一个带有必需参数(A),一些可选参数(B,C)和其他参数(Z)的函数
const doTheThing = (a, b = 'B', c = 'C', ...z) => {
console.log(a, b, c, z);
}
I have cases where I would like to call the function without specifying the optional parameters, but still specify the rest parameter "Z" 在某些情况下,我想在不指定可选参数的情况下调用该函数,但仍然指定其余参数“ Z”
doTheThing('A', ...'Z');
Expected Output: 预期产量:
'A', 'B', 'C', 'Z'
Unfortunately, I get the following: 不幸的是,我得到以下信息:
Parsing error: Shorthand property assignments are valid only in destructuring patterns
How do I go about solving this? 我该如何解决呢?
JavaScript doesn't allow supplying named parameters or any sort of parameter skipping, so it's not possible to do what you want with the function in its current form. JavaScript不允许提供命名参数或任何形式的参数跳过,因此无法使用当前形式的函数来执行所需的操作。 Here are some alternatives, though:
不过,这里有一些替代方法:
Instead of accepting multiple parameters 而不是接受多个参数
func = (a, b, c) => { /* operate with parameters */ }
func("One", "Two", "Three")
your function will instead accept an object 您的函数将改为接受一个对象
func = config => { /* operate with config */ }
func({a: "One", b: "Two", c: "Three"})
This is a common pattern in JavaScript because it allows you to almost name your variables and doesn't require you pass them in the correct order.. It makes it easy to pass a large quantity of them and it can also make it easy to default them, too. 这是JavaScript中的一种常见模式,因为它允许您几乎命名变量,并且不需要以正确的顺序传递它们。它可以轻松传递大量变量,还可以使其易于默认他们也是。
const doTheThing = (config) => { const defaultProperties = { b: "B", c: "C" } const {a, b, c, ...rest} = Object.assign({}, defaultProperties, config); const z = Object.values(rest); //extract their values, otherwise you get an object console.log(a, b, c, z); } doTheThing({a: "A", x: "X", y: "Y", z: "Z"});
It is slightly clunky to use with rest parameters but not unworkable. 与rest参数一起使用时有点笨拙,但并非不可行。
However, it does mean that it may be harder to see what parameters you can pass and what is required, if you have a large number of them. 但是,这确实意味着,如果您有很多参数,则可能很难看清可以传递哪些参数以及需要哪些参数。
You create a builder object - it serves to hold values until you call the final method at which point it takes all parameters and constructs an object in one go. 您将创建一个构建器对象-它用于保存值,直到调用final方法为止,此时将接受所有参数并一次性构造一个对象。
This is how more Object Oriented languages handle having a multitude of parameters where you can even have some of them optional. 这就是更多面向对象语言处理大量参数的方式,您甚至可以选择其中一些参数。 It's not really common to see builders defined like this in JavaScript but it's not too strange, either.
在JavaScript中看到这样定义的构建器并不是很常见,但是也不太奇怪。 If you use classes already or even TypeScript, then this is probably a better fit.
如果您已经使用类,甚至使用TypeScript,则可能更合适。
class DoTheThingBuilder { constructor() { this.a = null; this.b = "B"; this.c = "C"; this.z = null; } withA(a) { this.a = a; return this; } withB(b) { this.b = b; return this; } withC(c) { this.c = c; return this; } withEverythingElse(...z) { this.z = z; return this; } doTheActualThing() { const {a, b, c, z} = this; console.log(a, b, c, z); } } const builder = new DoTheThingBuilder(); builder .withA("A") .withEverythingElse("X", "Y", "Z") .doTheActualThing();
As you can see, this can be pretty verbose for some simple tasks. 如您所见,对于某些简单任务,这可能非常冗长。 It is a big overkill for this example, but perhaps in actual usage, you might find it helps.
对于此示例来说,这是一个很大的矫kill过正,但是也许在实际使用中,您可能会发现它有所帮助。
I've deviated a bit from the usual approach - normally, you would set all parameters needed with the builder and finally call .build()
which constructs an object . 我与通常的方法有所不同-通常,您将设置构建器所需的所有参数,最后调用构造一个对象的
.build()
。 In this case, I basically renamed build
to doTheActualThing
and it's executing the function. 在这种情况下,我基本上将
build
重命名为doTheActualThing
并且它正在执行该功能。
The concept of currying is quite simple - instead of having one function that accepts several parameters currying的概念非常简单-而不是拥有一个接受多个参数的函数
func = (a, b, c) => { /* operate with parameters */ }
you have a function that takes one parameter, that returns a function that takes the second parameter, that returns another function, etc., until all parameters are satisfied, at which point the full function is executed. 您有一个带有一个参数的函数,该函数返回一个带有第二个参数的函数,返回另一个函数,依此类推,直到满足所有参数为止,然后执行完整的函数。
func = a => b => c => { /* operate with parameters */ }
In many ways, this is the functional equivalent of the OO Builder pattern. 在许多方面,这与OO Builder模式等效。
const doTheThing = (a) => (b = "B") => (c = 'C') => (...z) => console.log(a, b, c, z); doTheThing("A")()()("X", "Y", "Z");
This way you can skip the second and third parameter by not supplying them and you'd get the defaults. 这样,您可以通过不提供第二个和第三个参数来跳过它们,从而获得默认值。 It's also way shorter than a builder.
它也比生成器短。 However, reading the function can be a bit weird.
但是,阅读该功能可能会有些奇怪。
That is not possible and very error-prone. 这是不可能的,而且很容易出错。 The point of naming your parameters is to know what they are and in what order they are coming.
命名参数的关键是要知道它们是什么以及它们以什么顺序出现。
You could achieve something similar using object as a function parameter: 使用object作为函数参数,您可以实现类似的效果:
const doTheThing = ({ a, b = "B", c = "C", others = {} }) => {
const params = { a, b, c, ...others }; // this will merge your parameters into one object
console.log(params);
}
doTheThing({ a: "A", others: { z: "Z" }});
This will log A, B, C, Z. Demo: https://codepen.io/tomekbuszewski/pen/jQqmNL?editors=0011 这将记录A,B,C,Z。演示: https : //codepen.io/tomekbuszewski/pen/jQqmNL? editors = 0011
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.