具有默认解构参数的Babel ES6类未定义

时间:2016-05-23 02:07:15

标签: default destructuring es6-class

我有一个ES6类,默认参数如下:

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
}

当我创建类的实例时,它在我提供值时按预期工作。

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

但是当我实例化一个没有值的实例时:

new Class()

它会抛出一个未定义的错误。这种方法似乎与标准函数声明/表达式一起使用。知道我在这里失踪的是什么吗?

提前感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:3)

我同意它有点难看,但它的发生是因为babel将其转化为类似的东西:

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

您正在设置对象属性的默认值,但不是对象本身的默认值。所以这是可以解决的。如果巴贝尔为我们这样做会很好,但它并没有。

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

// 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()

答案 1 :(得分: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 test

Compiled Babel ES5