【问题标题】:How to pass default for named parameters in javascript如何在javascript中为命名参数传递默认值
【发布时间】:2020-09-16 01:44:49
【问题描述】:

我在 typescript 中有一个使用命名参数的方法,如下所示

public foo({x, y, z , m , n} : {x:string, y: number, z: number, m?:string, n?:number}) {
}

参数mn 将由另一个对象提供,例如

const default = { m : 'M', n :10, o:6 }

现在我想像下面这样调用 foo 并且我希望添加默认参数而不在调用中显式传递它们

  foo({x:'x', y: 5, z: 0})

所以我的问题是如何在foo 的正文中应用default 或在调用之前以某种方式拦截foo 并应用default

public foo({x, y, z , m , n} = {x:string, y: number, z: number, m?:string, n?:number}) {
   // for example how to apply default here

}

请注意,为简单起见,我减少了参数数量

我也知道以下这些解决方案,我正在寻找样板代码更少的东西

public foo({x, y, z , m , n} = {x:string, y: number, z: number, m?:string, n?:number}) {
   if (!m) {
     m = default.m;
   }
   if (!n) {
     n = default.n;
   }

}

foo({...default, x:'x', y: 5, z: 0 });

【问题讨论】:

  • 您可能可以在这里使用装饰器做一些事情,但我不确定它是否会比foo({...default, x:'x', y: 5, z: 0 }); 少得多的样板。不过,也许更可重用。

标签: javascript typescript named-parameters


【解决方案1】:

对于合并,您需要使用 de-structure 进行合并。 default 分配在这里不起作用。仅当对象在传递值时未定义时,默认分配才有效。所以你需要将默认值与传递的值合并。

请检查代码中的注释。

interface Foo {
  x: string;
  y: number;
  z: number;
  m?: string;
  n?: number;
  o?: number;
}
const defaultValue = { m: "M", n: 10, o: 6 } as Foo;
class A {
  public foo(props: Foo) {
    const { x, y, z, m, n } = { ...defaultValue, ...props };
    console.log(x, y, z, m, n);
  }
  public foo2({ x, y, z, m = defaultValue.m, n = defaultValue.n }: Foo) {
    // this will work, but verbose
    console.log(x, y, z, m, n);
  }
  public foo1({ x, y, z, m, n }: Foo = defaultValue) {
    // this will work only if foo1 called without argument
    console.log(x, y, z, m, n);
  }
  public print() {
    this.foo({ x: "x", y: 5, z: 0 }); // x 5 0 M 10
    this.foo1(); // undefined undefined undefined 'M' 10
    this.foo1({ x: "x", y: 5, z: 0 }); // x 5 0 undefined undefined
    this.foo2({ x: "x", y: 5, z: 0 }); // x 5 0 M 10
  }
}
const a = new A();
a.print();

foofoo2 函数将起作用。但是,如果参数很少,则 foo2 非常冗长。使用Object.assign(){...} 合并值。

【讨论】:

    【解决方案2】:

    在函数内部组合和销毁对象怎么样?

    type someType = {x:string, y: number, z: number, m?:string, n?:number};
    const initialValues = { m : 'M', n :10, o:6 }
    
    function foo(obj: someType) {
      const {x, y, z , m , n} = {
        ...initialValues,
        ...obj
      }
    
    }
    

    【讨论】:

      【解决方案3】:

      您可以在参数本身中添加一个默认值,如下所示:

      public foo({x, y, z , m = 'a' , n = 10} = {x:string, y: number, z: number, m?:string, n?:number}) {
      }
      

      如果你传递一个值,默认值将被覆盖。通过这种方式,您甚至不需要 if 来检查值的存在。

      您仍然可以将方法称为:

      foo({...default, x:'x', y: 5, z: 0 });

      【讨论】:

        猜你喜欢
        • 2017-11-08
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 2012-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-30
        相关资源
        最近更新 更多