新しいメソッドで渡されない場合にプロパティにデフォルト値を割り当てる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でどのように機能するかを理解していないのかもしれません。
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/ での実行もテストおよび確認済み
Object.assignも同様に機能します
class RenderProperties {
constructor(options = {}){
Object.assign(this, {
fill : false,
fillStyle : 'rgba(0, 255, 0, 0.5)',
lineWidth : 1,
strokeStyle : '#00FF00'
}, options);
}
}
私は次を提案します:
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'});
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';
コンストラクターを通過するパラメーターがない場合、事前設定されたデフォルト値が割り当てられます。
class User {
constructor(fullName = "fooName", lastName, canAccess = false) {
this.fullName = fullName;
this.lastName = lastName;
this.canAccess = canAccess;
}
}
プロトタイプに追加するだけです。 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"
});
同様の質問をしたところ、解決策を思いついた後にこの質問を見つけたので、ここにも投稿したいと思いました。
私の質問は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();
ここで行っているのは、options引数を分解することだけです。未定義のユースケースを3進数で処理します。
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);
だから私はこの質問の答えを読んでいて、拡張クラスで簡単に機能するものを見つけられなかったので、これを思いつきました。
最初に、オブジェクトに別のオブジェクトのプロパティがあるかどうかをチェックする関数を作成します。
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'