简体   繁体   English

我可以绕过可选参数而仍然在Javascript中设置rest参数吗?

[英]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: 不过,这里有一些替代方法:

Plain JavaScript approach: a configuration Object as parameter 普通的JavaScript方法:将配置对象作为参数

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. 但是,这确实意味着,如果您有很多参数,则可能很难看清可以传递哪些参数以及需要哪些参数。

Object Oriented approach: Builder pattern 面向对象的方法:构建器模式

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并且它正在执行该功能。

Functional approach: Currying 功能方法:咖喱

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.

相关问题 如何处理JavaScript中的可选参数? - How can I deal with optional parameters in JavaScript? 调用JavaScript方法时绕过set参数? - Bypass a set parameter when calling a JavaScript method? 如何使用JavaScript创建包含多个可选参数的搜索? - How can I create a search with multiple, optional, parameters using JavaScript? 在JavaScript中,如何创建一个带有可选参数的function? - In JavaScript, how can I create a function with an optional parameter? 向 JavaScript 中已有可选参数的构造函数添加可选参数 - Add an optional parameter to a constructor that already has optional parameters in JavaScript 如何在JavaScript getusermedia中设置此参数? - How can I set this parameter in JavaScript getusermedia? JavaScript函数-跳过可选参数时出现命名参数问题 - JavaScript function - named parameters issue when skipping an optional parameter 我应该如何在JavaScript中传递两个函数作为参数,两者都可以是可选的 - How can should I pass two functions as parameters, both can be optional, in javascript Typescript:如果派生类中未传递任何值,如何设置可选参数? - Typescript: How can I set an optional parameter if no value is passed in a derived class? javascript函数中的可选参数 - Optional parameters in javascript function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM