web-dev-qa-db-ja.com

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:Undefinedのプロパティ 'c'を設定できません。

クラスがjavascriptでどのように機能するかを理解していないのかもしれません。

14
Leonardo Alves

ES6を使用する場合は、ES6のすべてを使用しないでください。つまり、パラメーターのデフォルト値と割り当ての破壊

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/

編集: https://babeljs.io/repl/ での実行もテストおよび確認済み

21
Jaromanda X

Object.assignも同様に機能します

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

私は次を提案します:

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:未定義のプロパティ 'c'を設定できません。

これは、optionsが未定義であることを意味します。

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

コンストラクターを通過するパラメーターがない場合、事前設定されたデフォルト値が割り当てられます。

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

プロトタイプに追加するだけです。 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"
});
0
rich remer

同様の質問をしたところ、解決策を思いついた後にこの質問を見つけたので、ここにも投稿したいと思いました。

私の質問は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引数を分解することだけです。未定義のユースケースを3進数で処理します。

0
pkloss

MDN web docsのデフォルトパラメータ に基づいた、より短く、よりクリーンなバージョン

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

オブジェクトを渡す。

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

だから私はこの質問の答えを読んでいて、拡張クラスで簡単に機能するものを見つけられなかったので、これを思いつきました。

最初に、オブジェクトに別のオブジェクトのプロパティがあるかどうかをチェックする関数を作成します。

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

EXAMPLE:

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'
0
ElrohirGT FAGD