非推奨の警告: watch() および unwatch() は使用しないでください!これら 2 つのメソッドはバージョン 58 より前の Firefox しか実装しておらず、Firefox 58 以降で非推奨および削除されます。また、ウォッチポイントを使用するとパフォーマンスに大きな悪影響があり、特に window のようなグローバルオブジェクトで使用すると顕著です。通常は、代わりに セッターとゲッター または proxy を使用できます。

watch() メソッドはプロパティに値が代入されるのを監視し、代入された際に関数を実行します。

構文

obj.watch(prop, handler)

引数

prop
変化を監視したいオブジェクトのプロパティの名前。
handler
指定したプロパティの値が変化したときに呼び出す関数。

戻り値

undefined

説明

オブジェクト中で名前が 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() を呼び出すと、そのプロパティへ前に割り当てられていたハンドラーをオーバーライドします。

watchunwatch を使う

var o = { p : 1 };

o.watch("p", function (id,oldval,newval) {
  console.log(
    "o." + id + " は " +
    oldval + " から " +
    newval + " に変更されました"
  );

  return newval;
});

o.p = 2;
o.p = 3;
delete o.p;
o.p = 4;

o.unwatch('p');
o.p = 5;

コンソールへの出力は以下の様なものになります。

o.p は 1 から 2 に変更されました
o.p は 2 から 3 に変更されました
o.p は undefined から 4 に変更されました

watch を使ってオブジェクトのプロパティの妥当性を評価する

watch を使えば、オブジェクトのプロパティへのあらゆる代入操作を検査することができます。この例はどの Person も常に妥当な名前と 0 から 200 までの年齢を保持することを保証します。

Person = function(name, age) {
  this.watch('age', Person.prototype._isValidAssignment);
  this.watch('name', Person.prototype._isValidAssignment);
  this.name = name;
  this.age = age;
};

Person.prototype.toString = function() {
  return this.name + ', ' + this.age;
};

Person.prototype._isValidAssignment = function(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;
}

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

仕様

どの仕様書にも含まれていません。JavaScript 1.2 で実装されました。

ブラウザー実装状況

機能ChromeEdgeFirefoxInternet ExplorerOperaSafari
基本対応 なし なし1 — 58 なし なし なし
機能Android webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
基本対応 なし なし なし4 — 58 なし なし なし

互換性情報

  • この Polyfill は、すべての ES5 互換ブラウザーに watch をもたらします。
  • Proxy を使用すると、プロパティの代入操作をさらに深く変更できます。
  • Firefox 23 より、Documentwatch() を呼び出すと TypeError が発生します (バグ 903332)。このリグレッションは Firefox 27 で修正しました。

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: yyss, sa-inu, teoli, hinaloe, ethertank, Mgjbot, Potappo, Yuichirou
 最終更新者: yyss,