1

I have a ES6 class with default parameters like so:

constructor({
    // defaults
    defaultOne     = 'default value one',
    defaultTwo     = ['default','value','two],
    defaultThree   = 'default value three,
}) {
    this.defaultOne   = defaultOne
    this.defaultTwo   = defaultTwo
    this.defaultThree = defaultThree

    return this
}

When I create an instance of the class it works as expected when I provide values.

new Class({defaultOne: 'one',defaultTwo: ['t','w','o'], defaultThree: 'three'})

But when I instantiate an instance with no values:

new Class()

It throws an undefined error. This approach seems to work fine with standard function declarations/expressions. Any idea what I'm missing here?

Thanks in advance for any help on this.

4

2 回答 2

4

我同意这有点难看,但它发生是因为 babel 将其转换为:

constructor(_ref) {
  var _defaultOne = _ref.defaultOne; // « this is where it goes wrong. _ref = undefined
}

您正在为对象属性设置默认值,但不是为对象本身设置默认值。所以这是可以修复的。如果 babel 为我们这样做就好了,但事实并非如此。

要解决此问题,请为参数对象提供默认值,而不是:

// es6
const foo = ({ bar = 'baz' }) => {};

// transpiled
var foo = function foo(_ref) {
  var _ref$bar = _ref.bar;
  var bar = _ref$bar === undefined ? 'baz' : _ref$bar;
};

你需要写

// es6
const foo = ({ bar = 'baz'} = {}) => {};

// transpiled
var foo = function foo() {
  var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

  var _ref$bar = _ref.bar;
  var bar = _ref$bar === undefined ? 'baz' : _ref$bar;
};

要完整,您的示例将变为:

constructor({
  // defaults
  defaultOne     = 'default value one',
  defaultTwo     = ['default','value','two'],
  defaultThree   = 'default value three',
} = {}) { // « notice the change on this line
  this.defaultOne   = defaultOne
  this.defaultTwo   = defaultTwo
  this.defaultThree = defaultThree
}

new Class({defaultOne: 'one',defaultTwo: ['t','w','o'], defaultThree: 'three'})
new Class()
于 2016-08-02T09:47:35.707 回答
0

虽然规范似乎不允许您直接解构类的参数,但此解决方案提供了非常相似的语法:

class Test {
    constructor(options) {
      let {
        defaultOne   : defaultOne   = 'default one value', 
        defaultTwo   : defaultTwo   = 'default two value', 
        defaultThree : defaultThree = 'default three value'
      } = (options) ? options:{};

      this.defaultOne   = defaultOne;
      this.defaultTwo   = defaultTwo;
      this.defaultThree = defaultThree;

      this.init();
    }

  init() {
    console.log(this.defaultOne);
    console.log(this.defaultTwo);
    console.log(this.defaultThree);
  }
}

new Test({defaultOne: 'Override default one value'});
new Test();

ES6 通天塔测试

编译的 Babel ES5

于 2016-05-23T03:33:34.400 回答