web-dev-qa-db-fra.com

Classes ES6 Valeur par défaut

Est-il possible de créer une classe ES6, qui attribue une valeur par défaut à une propriété si elle n'est pas passée dans la nouvelle méthode?

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'});

Si j'essaie de faire cela avec ce code, en compilant avec babeljs, j'obtiens un TypeError: Impossible de définir la propriété 'c' de non définie. 

Peut-être que je ne comprends pas comment les classes fonctionnent en javascript.

13
Leonardo Alves

Si vous comptez utiliser ES6, pourquoi ne pas utiliser toutes les fonctions de ES6, c’est-à-dire les valeurs par défaut pour les paramètres et l’affectation de la déstructuration

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: également testé et confirmé pour une exécution sur https://babeljs.io/repl/

20
Jaromanda X

Object.assign travaille aussi pour moi

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

Je suggérerais ce qui suit:

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'});
5
Mathieu Dutour

TypeError: Impossible de définir la propriété 'c' de non définie.

Cela signifie que options est indéfini.

Assurez-vous que l'objet options existe, d'abord:

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';
}

Ou, gentil et court:

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';
1
Cerbrus

Je voudrais juste l'ajouter au prototype. Les classes ES6 n'étant que du sucre syntaxique, vous pouvez utiliser toutes les techniques d'héritage de prototypes standard disponibles avant l'introduction du mot clé 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"
});
0
rich remer

Je viens de poser une question similaire et j'ai trouvé cette question après avoir trouvé une solution. J'ai donc pensé la poster ici aussi. 

Ma question était spécifique à ES6 et utilisait la déconstruction pour définir des paramètres par défaut pour une classe. Il semble que les spécifications ne vous permettent pas de déconstruire directement les arguments, sauf si vous faites quelque chose de similaire à ce que @Jaromanda X a fait. 

Je voulais quelque chose de plus court et de plus propre, et j'ai fini par utiliser le modèle suivant:

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 test Babel

Compilé Babel ES5

Nous ne faisons que déconstruire l'argument des options, et nous traitons le cas d'utilisation non défini avec un ternaire.

0
pkloss

Version plus courte et plus propre basée sur Paramètres par défaut des documents Web 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);

En passant un objet .

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 options = {
  a: 'a value',
  b: 'b value'
}

let myClassWithValue = new myClass(options);

console.log(myClassWithValue);

0
AESTHETICS