繁体   English   中英

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

[英]Can I bypass optional parameters and still set a rest parameter in Javascript?

我有一个带有必需参数(A),一些可选参数(B,C)和其他参数(Z)的函数

const doTheThing = (a, b = 'B', c = 'C', ...z) => {
  console.log(a, b, c, z);
}

在某些情况下,我想在不指定可选参数的情况下调用该函数,但仍然指定其余参数“ Z”

doTheThing('A', ...'Z');

预期产量:

'A', 'B', 'C', 'Z'

不幸的是,我得到以下信息:

Parsing error: Shorthand property assignments are valid only in destructuring patterns

我该如何解决呢?

JavaScript不允许提供命名参数或任何形式的参数跳过,因此无法使用当前形式的函数来执行所需的操作。 不过,这里有一些替代方法:

普通的JavaScript方法:将配置对象作为参数

而不是接受多个参数

func = (a, b, c) => { /* operate with parameters */ } 
func("One", "Two", "Three")

您的函数将改为接受一个对象

func = config => { /* operate with config */ }
func({a: "One", b: "Two", c: "Three"})

这是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"}); 

与rest参数一起使用时有点笨拙,但并非不可行。

但是,这确实意味着,如果您有很多参数,则可能很难看清可以传递哪些参数以及需要哪些参数。

面向对象的方法:构建器模式

您将创建一个构建器对象-它用于保存值,直到调用final方法为止,此时将接受所有参数并一次性构造一个对象。

这就是更多面向对象语言处理大量参数的方式,您甚至可以选择其中一些参数。 在JavaScript中看到这样定义的构建器并不是很常见,但是也不太奇怪。 如果您已经使用类,甚至使用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(); 

如您所见,对于某些简单任务,这可能非常冗长。 对于此示例来说,这是一个很大的矫kill过正,但是也许在实际使用中,您可能会发现它有所帮助。

我与通常的方法有所不同-通常,您将设置构建器所需的所有参数,最后调用构造一个对象的 .build() 在这种情况下,我基本上将build重命名为doTheActualThing并且它正在执行该功能。

功能方法:咖喱

currying的概念非常简单-而不是拥有一个接受多个参数的函数

func = (a, b, c) => { /* operate with parameters */ }

您有一个带有一个参数的函数,该函数返回一个带有第二个参数的函数,返回另一个函数,依此类推,直到满足所有参数为止,然后执行完整的函数。

func = a => b => c => { /* operate with parameters */ }

在许多方面,这与OO Builder模式等效。

 const doTheThing = (a) => (b = "B") => (c = 'C') => (...z) => console.log(a, b, c, z); doTheThing("A")()()("X", "Y", "Z"); 

这样,您可以通过不提供第二个和第三个参数来跳过它们,从而获得默认值。 它也比生成器短。 但是,阅读该功能可能会有些奇怪。

这是不可能的,而且很容易出错。 命名参数的关键是要知道它们是什么以及它们以什么顺序出现。

使用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" }});

这将记录A,B,C,Z。演示: https//codepen.io/tomekbuszewski/pen/jQqmNL? editors = 0011

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM