非推奨の警告: watch()
および unwatch()
は使用しないでください!これら 2 つのメソッドはバージョン 58 より前の Firefox しか実装しておらず、Firefox 58 以降で非推奨および削除されます。また、ウォッチポイントを使用するとパフォーマンスに大きな悪影響があり、特に window
のようなグローバルオブジェクトで使用すると顕著です。通常は、代わりに セッターとゲッター または proxy を使用できます。
watch()
メソッドはプロパティに値が代入されるのを監視し、代入された際に関数を実行します。
構文
obj.watch(prop, handler)
引数
prop
- 変化を監視したいオブジェクトのプロパティの名前。
handler
- 指定したプロパティの値が変化したときに呼び出す関数。
戻り値
説明
オブジェクト中で名前が prop
であるプロパティへの代入処理を監視し、prop
に値がセットされたときには毎回 handler(prop, oldval, newval)
を呼び出して、その戻り値をプロパティに保存します。ウォッチポイントは修正した newval
を返す (あるいは oldval
を返す) ことにより、値の代入をフィルタリング (または無効化) することができます。
ウォッチポイントがセットされたプロパティを削除しても、そのウォッチポイントは消滅しません。その後プロパティを再生成しても、ウォッチポイントは効果を持ち続けます。
ウォッチポイントを削除するには、unwatch()
メソッドを使います。デフォルトで、watch
メソッドは Object
の子孫であるあらゆるオブジェクトに継承されています。
JavaScript のデバッガーは他のデバッグ用オプションと同様に、このメソッドで使用されるものと機能的に似たものを有しています。デバッガーについての情報は Venkman をご覧ください。
Firefox では、ネイティブコードからではなくスクリプトで代入した場合に限り handler
を呼び出します。例えばユーザーが現在のドキュメントでアンカーへのリンクをクリックししたときに、window.watch('location', myHandler)
は myHandler
を呼び出しません。しかし、window.location += '#myAnchor'
は myHandler
を呼び出します。
注記: 特定のプロパティのためにオブジェクトで watch()
を呼び出すと、そのプロパティへ前に割り当てられていたハンドラーをオーバーライドします。
例
watch
と unwatch
を使う
const o = { p: 1 };
o.watch('p', (id, oldval, newval) => {
console.log('o.' + id + ' changed from ' + oldval + ' to ' + newval);
return newval;
});
o.p = 2;
o.p = 3;
delete o.p;
o.p = 4;
o.unwatch('p');
o.p = 5;
このスクリプトは以下のように表示します。
o.p changed from 1 to 2 o.p changed from 2 to 3 o.p changed from undefined to 4
watch() を使用してオブジェクトのプロパティを検証する
watch
を使えば、オブジェクトのプロパティへのあらゆる代入操作を検査することができます。この例はどの Person も常に妥当な名前と 0 から 200 までの年齢を保持することを保証します。
class Person {
constructor(name, age) {
this.watch('age', this._isValidAssignment.bind(this));
this.watch('name', this._isValidAssignment.bind(this));
this.name = name;
this.age = age;
}
toString() {
return this.name + ', ' + this.age;
}
_isValidAssignment(id, oldval, newval) {
if (id === 'name' && (!newval || newval.length > 30)) {
throw new RangeError('invalid name for ' + this);
}
if (id === 'age' && (newval < 0 || newval > 200)) {
throw new RangeError('invalid age for ' + this);
}
return newval;
}
}
const will = new Person('Will', 29);
console.log(will); // Will, 29
try {
will.name = '';
} catch (e) {
console.log(e);
}
try {
will.age = -4;
} catch (e) {
console.log(e);
}
このスクリプトは以下のように表示します。
Will, 29 RangeError: invalid name for Will, 29 RangeError: invalid age for Will, 29
仕様書
どの標準にも含まれていません。
ブラウザー実装状況
互換性情報
- この Polyfill は、すべての ES5 互換ブラウザーに
watch
をもたらします。 Proxy
を使用すると、プロパティの代入操作をさらに深く変更できます。- Firefox 23 より、
Document
オブジェクトでwatch()
を呼び出すとTypeError
が発生します (bug 903332)。このリグレッションは Firefox 27 で修正しました。