没有解构的命名默认 ES6 参数

Named default ES6 parameter without destructuration

我正在尝试使用 babel 在 ES7 中设置默认选项。这是我能做的:

class Foo {
  constructor({key='value', foo='bar', answer=42}) {
    this.key = key; 
    this.foo = foo;
    this.number = number;
  }
}

这可能适用于此示例,但我想知道如何分配非常大的配置对象; 这是我想做的一个例子:

class Foo {
  constructor(opts = {key='value', foo='bar', answer=42}) {
    this.opts = opts;
  }
}

然而这并不能编译。我试着这样做:

class Foo {
  constructor(opts = {key:'value', foo:'bar', answer:42}) {
    this.opts = opts;
  }
}

但随后它会替换整个对象,如下所示:

let foo = new Foo({key: 'foobar'});

console.log(foo.opts);
// {key: 'foobar'} is what is displayed
// When I want {key: 'foobar', foo:'bar', answer:42}

class Foo {
  constructor({key='value', foo='bar', answer=42} = {}) {
    ...
  }
}

这是 ES6 解构特性,并非特定于 ECMAScript 7 (ECMAScript Next) 提案。

不解构通常是用对象cloning/merging完成的,Object.assign来帮忙:

class Foo {
  constructor(opts = {}) {
    this.opts = Object.assign({
      key: 'value',
      foo: 'bar',
      answer: 42
    }, opts);
  }
}

我不认为你可以使用 ES6 可选参数(对象作为带有可选键的参数)来做到这一点,因为当你调用构造函数时,它是一个带有新引用的新对象。那是因为它正在被替换。

但是,作为一个建议,如果你想处理一个大的选项对象,一种常见的方法是在某处存储一个 默认选项 对象并将该对象与传递的对象合并你实例化它。

类似的东西:

class Foo {

  constructor(opts) {
    this.opts = Object.assign({}, Foo.defaultOptions, opts)
    console.log(this.opts)
  }
}

Foo.defaultOptions = {
    key: 'value', 
    foo: 'bar',
    answer: 42
}

let foo = new Foo({key: 'another value'})
//{ key: 'another value', foo: 'bar', answer: 42 }

您可以与 Object.assign 合并(请注意,它不会执行深度合并 - 嵌套对象被替换)。

或者,如果你想将默认选项对象声明为 class 变量(不是在最后,在 class 声明之后,或在构造函数内部),因为你正在使用 babel,您可以使用 this 插件并执行此操作:

class Foo {

    defaultOptions = {
        key: 'value', 
        foo: 'bar',
        answer: 42
    }

    constructor(opts) {
        this.opts = Object.assign({}, this.defaultOptions, opts)
        console.log(this.opts)
    }
}

更具可读性。