ES6 Классы Значение по умолчанию

Можно ли создать класс ES6, который присваивает значение по умолчанию для свойства, если оно не передано в новом методе?

class myClass {
    constructor(options) {
        this.a = typeof options.a !== 'undefined' ? options.a : 'default a value';
        this.b = typeof options.b !== 'undefined' ? options.b : 'default b value';
        this.c = typeof options.c !== 'undefined' ? options.c : 'default c value';
    }
}

var myClassWithValue = new myClass({a:'a value', b: 'b value'});

Если я попытаюсь сделать это с помощью этого кода, компилируя с babeljs, я получаю TypeError: Не могу установить свойство 'c' из undefined.

Возможно, я не понимаю, как работают классы в javascript.

Ответ 1

Если вы собираетесь использовать ES6, почему бы не использовать все ES6, то есть значения по умолчанию для параметров и назначение destructuring

class myClass {
  constructor({a = 'default a value', b = 'default b value', c = 'default c value'} = {a:'default option a', b:'default option b', c:'default option c'}) {
    this.a = a;
    this.b = b;
    this.c = c;
  }
}
var v = new myClass({a:'a value', b: 'b value'});
console.log(v.toSource());
var w = new myClass();
console.log(w.toSource());

http://www.es6fiddle.net/ibxq6qcx/

edit: также проверено и подтверждено для запуска на https://babeljs.io/repl/

Ответ 2

Object.assign работает для меня, а также

class RenderProperties {
   constructor(options = {}){
        Object.assign(this, {
            fill : false, 
            fillStyle : 'rgba(0, 255, 0, 0.5)',
            lineWidth : 1,
            strokeStyle : '#00FF00'
        }, options);
    }
}

Ответ 3

Я бы предложил следующее:

class myClass {
  constructor(options) {
    const defaults = {
      a: 'default a value',
      b: 'default b value',
      c: 'default c value'
    };
    const populated = Object.assign(defaults, options);
    for (const key in populated) {
      if (populated.hasOwnProperty(key)) {
        this[key] = populated[key];
      }
    }
  }
}

var myClassWithValue = new myClass({a:'a value', b: 'b value'});

Ответ 4

TypeError: Невозможно установить свойство 'c' из undefined.

Это означает, что options - undefined.

Убедитесь, что объект options существует, сначала:

if(options){
    this.a = typeof options.a !== 'undefined' ? options.a : 'default a value';
    this.b = typeof options.b !== 'undefined' ? options.b : 'default b value';
    this.c = typeof options.c !== 'undefined' ? options.c : 'default c value';
}else{
    this.a = 'default a value';
    this.b = 'default b value';
    this.c = 'default c value';
}

Или, красивый и короткий:

options = options || {};
this.a = typeof options.a !== 'undefined' ? options.a : 'default a value';
this.b = typeof options.b !== 'undefined' ? options.b : 'default b value';
this.c = typeof options.c !== 'undefined' ? options.c : 'default c value';

Ответ 5

Я просто задал аналогичный вопрос и нашел этот вопрос после того, как придумал решение, поэтому я подумал, что я тоже опубликую его здесь.

Мой вопрос касался ES6 и использования деконструкции для установки параметров по умолчанию для класса. Кажется, спецификация не позволяет вам напрямую деконструировать аргументы, если вы не делаете что-то похожее на то, что сделал @Jaromanda X.

Я хотел что-то более короткое и более чистое, и в итоге использовал следующий шаблон:

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

Скомпилированный Babel ES5

Все, что мы делаем здесь, это деконструкция аргумента options, и мы обрабатываем прецедент использования undefined с тройным.

Ответ 6

Более короткая и более чистая версия на основе Параметры по умолчанию из веб-документов MDN.

class myClass {
  constructor(
  a = 'default a value',
  b = 'default b value',
  c = 'default c value'
  ) {
      this.a = a;
      this.b = b;
      this.c = c;
    }
}

let myClassWithValue = new myClass('a value','b value');

console.log(myClassWithValue);

Ответ 7

Я бы просто добавил это к прототипу. Классы ES6 являются просто синтаксическим сахаром, поэтому вы можете использовать все стандартные методы наследования прототипов, которые были доступны до введения ключевого слова class.

const {assign, seal} = Object;

class MyClass {
    constructor(options) {
        assign(seal(this), options);
    }
}

assign(MyClass.prototype, {
    a: "default a value",
    b: "default b value",
    c: "default c value"
});

Ответ 8

Так что я читал ответы на этот вопрос, и я не нашел такой, которая бы легко работала с расширенными классами, поэтому я придумал это.

Сначала вы создаете функцию, которая проверяет, есть ли у объекта свойства другого объекта:

function checkValues(values = {}, targets) {
  values = Object.keys(values);
  targets = Object.keys(targets);
  return values.every(keyValor => targets.includes(keyValor));
}

Затем в классе вы определяете значения по умолчанию следующим образом:

class Error {
  constructor(options = {}) {
    //Define default values
    var values = {
      title: '',
      status: 500,
      mesagge: ''
    };
    //Check if options has properties of values
    var valid = checkValues(values, options);
    //If options doesn't has all the properties of values, assign default values to options
    if (!valid) {
      options = valores
    }
    //Asign options to the class
    Object.assign(this, options);
  }
}

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

class FormError extends Error{
  constructor (options = {}){
    var values = {
      invalidParams: [{name:'', reason: ''}]
    };
    var valid = checkValues(values, options);
    if (!valid) { options = values}
    super(options);
    Object.assign(this, options);
  }
}

ПРИМЕР:

var a = new Error();
var b = new FormError();
var c = new FormError({invalidParams: [{name: 'User', reason: 'It has to be a string!'}]});
console.log(a, b, c);

Примечание: это работает, только если вы хотите иметь ВСЕ значения по умолчанию, а не только некоторые из них, например:

var e = new Error({message: 'This is an error'});
console.log(e.message);// ''
//Error e will only have the default values, and message would be empty.

var h = new FormError({title: 'FORM ERROR', status: 400});
console.log(h.title);//''
//Error h will only have the defaults because I didn't provide 'invalidParams'

Ответ 9

если нет параметров, проходящих через конструктор, ему присваивается значение по умолчанию, как это было задано заранее, я надеюсь, что помог!

class User {
  constructor(fullName = "fooName", lastName, canAccess = false) {
    this.fullName = fullName;
    this.lastName = lastName;
    this.canAccess = canAccess;
  }
}