オブジェクトのプロパティを操作する際エラーを検知する方法
オブジェクトのプロパティに対して値を設定更新する際、仮にエラーが発生した場合に今までであれば以下のような形式でハンドリングを行っていました。
const user = {};
try {
user.name = '太郎';
console.log('Success!');
} catch (e) {
console.error('Failed...');
}
console.log(user.name); // 太郎
delete user.name;
console.log(user.name); // undefined
上記でも十分わかりやすいですが、わざわざtry-catchを記述しなくてもReflectを利用すればプロパティの変更や削除に成功したかどうかはブール値として取得することが可能です。
const user = {};
if (Reflect.set(user, 'name', '太郎')) {
console.log('Success!');
} else {
console.error('Failed...');
}
console.log(Reflect.get(user, 'name')); // 太郎
if (Reflect.deleteProperty(user, 'name')) {
console.log('Success!');
} else {
console.error('Failed...');
}
オブジェクトのプロパティ操作をカスタマイズする方法
オブジェクトのプロパティに対して何らかの操作を実施する際、付随して何か特定の処理を実行する場合は以下のように記述するかと思います。
オブジェクトからプロパティを参照・変更するたびにログを出力する処理
const user = {
name: 'Alice',
age: 25
};
const name = user.name;
console.log(`user.nameが読み込まれました`);
user.age = 26;
console.log(`user.ageが更新されました`);
上記のようにオブジェクトのプロパティが読み込まれたり、参照されるたびにログを記述する必要があるのですが、ReflectとProxyを利用することで以下のように記述することができます。
const user = {
name: 'Alice',
age: 25
};
const handler = {
get(target, prop) {
console.log(`user.${prop}が読み込まれました`);
return Reflect.get(target, prop);
},
set(target, prop, value) {
console.log(`user.${prop}が更新されました`);
return Reflect.set(target, prop, value);
}
};
const proxy = new Proxy(user, handler);
const name = proxy.name; // 「user.${name}が読み込まれました」 と出力される
proxy.age = 26; // 「user.${age}が更新されました」 と出力される
上記の機能を利用することでバリデーションの実装なども可能になります。
const user = {
name: 'Alice',
age: 25
};
const handler = {
set(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new TypeError('数字で入力してね!');
}
console.log(`${prop} を ${value} に変更したよ`);
return Reflect.set(target, prop, value);
}
};
const proxy = new Proxy(user, handler);
try {
proxy.age = 'twenty-six'; // 「TypeError: 数字で入力してね!」がスローされる
} catch (e) {
console.error(e.message);
}
proxy.age = 26; // 「age を 26 に変更したよ」と出力される
console.log(proxy.age); // 26