JavaSciriptのプロパティとディスクリプターについて
JavaSciriptのプロパティとディスクリプターについてまとめました。
プロパティとディスクリプター
オブジェクトを作成するとプロパティには、値(バリュー)がセットされます。
実は、この値以外にもプロパティの設定値を保持しています。
- configurable
- enumerable
- writable
という3つを保持しています。
値を含めて上の4つをディスクリプターといいます。
これらの値を設定することで、プロパティの挙動を調整することができます。
プロパティの設定値
プロパティの設定値 | |
---|---|
value | 値 |
configurable | 設定変更の可否 |
enumarable | 列挙の可否 |
writable | 値の変更の可否 |
ディスクリプターの設定
const a = { p: 0 };
const descriptor = Object.getOwnPropertyDescriptor(a, 'p');
console.log(descriptor);
// {value: 0,
// writable: true,
// enumerable: true,
// configurable: true}
getOwnPropertyDescriptorでディスクリプターの設定をみることができます。
このように、オブジェクトリテラルで定義すると、すべてtrueで設定されていることがわかります。
プロパティの設定を変更してみます。
definePropertyで設定を変更することができます。
const b = {};
Object.defineProperty(b, 'p', {
value: 9,
writable: true,
});
const descriptor = Object.getOwnPropertyDescriptor(b, 'p');
// {value: 9,
// writable: true,
// enumerable: false,
// configurable: false}
b.p = 1;
console.log(descriptor);
console.log(b.p); //1
それぞれのプロパティには、ディスクリプターがあり、ディスクリプターの設定によって挙動が異なっているということを知っておくことが重要です。
setとgetを設定する
ディスクリプターで、setとgetを設定できます。
setとgetはオプションなので、設定されない場合はundefinedになります。
setとgetを設定すると特別な機能を追加することが可能です。
ディスクリプターで設定されるsetとgetのことをsetterとgetterといいます。
function Student(name, age) {
this._name = name;
this._age = age;
}
Object.defineProperty(Student.prototype, 'rename', {
get: function () {
console.log('こんにちは');
return `${this._name}さん`;
},
set: function (val) {
this._name = val;
},
});
const yamada = new Student('yamada', 40);
console.log(yamada.rename);
// こんにちは
// yamadaさん
console.log(yamada._name); //yamada
definePropertyでは、第一引数にディスクリプターを使って設定したいオブジェクトを渡します。
第二引数にgetとsetで使いたい値を指定します。そして、getとsetを設定します。
getには呼ばれた際の動作を書きます。
設定したプロパティに値を取りにいくようなことをするとgetが呼び出されます。
setは引数に設定された値が入ってきます。
yamada.rename = '山田';
console.log(yamada.rename);
// こんにちは
// 山田さん
console.log(yamada._name); //山田
getが呼ばれるたびに必ずgetterの関数が実行されることになるので、なんらかの処理をgetとsetをいれることができます。
同じことをES6のクラスを使うと次のように記述することができます。
class Student2 {
constructor(name, age) {
this._name = name;
this._age = age;
}
get rename() {
console.log('こんにちは');
return `${this._name}さん`;
}
set rename(val) {
this._name = val;
}
}
具体的なgetterとsetterの例はこちらを参考にしてみてください。