Babel 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 ответа

Я согласен, что это немного уродливо, но это происходит потому, что Вавилон передает это примерно так:

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

Хотя кажется, что спецификация не позволяет напрямую деконструировать аргументы класса, это решение имеет очень похожий синтаксис:

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

Другие вопросы по тегам