aboutsummaryrefslogtreecommitdiff
path: root/files/ja/archive/web/javascript/object.watch/index.html
blob: c97353adc9a1f3f3d7fc7ffe9dfa332be7c184ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
---
title: Object.prototype.watch()
slug: Archive/Web/JavaScript/Object.watch
tags:
  - Debugging
  - Deprecated
  - JavaScript
  - Method
  - Object
  - Obsolete
  - Prototype
  - メソッド
  - 廃止
  - 非推奨
translation_of: Archive/Web/JavaScript/Object.watch
---
<div>{{JSRef}}</div>

<div class="warning">
<p><strong>非推奨の警告:</strong> <code>watch()</code> および {{jsxref("Object.prototype.unwatch", "unwatch()")}} は使用しないでください!これら 2 つのメソッドはバージョン 58 より前の Firefox しか実装しておらず、<strong>Firefox 58 以降で非推奨および削除されます</strong>。また、ウォッチポイントを使用するとパフォーマンスに大きな悪影響があり、特に <code>window</code> のようなグローバルオブジェクトで使用すると顕著です。通常は、代わりに <a href="/ja/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">セッターとゲッター</a> または <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy">proxy</a> を使用できます。</p>
</div>

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

<h2 id="Syntax" name="Syntax">構文</h2>

<pre class="syntaxbox"><code><var>obj</var>.watch(<var>prop</var>, <var>handler</var>)</code></pre>

<h3 id="Parameters" name="Parameters">引数</h3>

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

<h3 id="Return_value" name="Return_value">戻り値</h3>

<p>{{jsxref("undefined")}}</p>

<h2 id="Description" name="Description">説明</h2>

<p>オブジェクト中で名前が <code>prop</code> であるプロパティへの代入処理を監視し、<code>prop</code> に値がセットされたときには毎回 <code>handler(prop, oldval, newval)</code> を呼び出して、その戻り値をプロパティに保存します。ウォッチポイントは修正した <code>newval</code> を返す (あるいは <code>oldval</code> を返す) ことにより、値の代入をフィルタリング (または無効化) することができます。</p>

<p>ウォッチポイントがセットされたプロパティを削除しても、そのウォッチポイントは消滅しません。その後プロパティを再生成しても、ウォッチポイントは効果を持ち続けます。</p>

<p>ウォッチポイントを削除するには、{{jsxref("Object.unwatch", "unwatch()")}} メソッドを使います。デフォルトで、<code>watch</code> メソッドは {{jsxref("Object")}} の子孫であるあらゆるオブジェクトに継承されています。</p>

<p>JavaScript のデバッガーは他のデバッグ用オプションと同様に、このメソッドで使用されるものと機能的に似たものを有しています。デバッガーについての情報は <a href="/ja/docs/Venkman">Venkman</a> をご覧ください。</p>

<p>Firefox では、ネイティブコードからではなくスクリプトで代入した場合に限り <code>handler</code> を呼び出します。例えばユーザーが現在のドキュメントでアンカーへのリンクをクリックししたときに、<code>window.watch('location', myHandler)</code><code>myHandler</code> を呼び出しません。しかし、<code>window.location += '#myAnchor'</code><code>myHandler</code> を呼び出します。</p>

<div class="note">
<p><strong>注記:</strong> 特定のプロパティのためにオブジェクトで <code>watch()</code> を呼び出すと、そのプロパティへ前に割り当てられていたハンドラーをオーバーライドします。</p>
</div>

<h2 id="Examples" name="Examples"></h2>

<h3 id="Using_watch_and_unwatch" name="Using_watch_and_unwatch"><code>watch</code><code>unwatch</code> を使う</h3>

<pre class="brush: js">const o = { p: 1 };

o.watch('p', (id, oldval, newval) =&gt; {
  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;
</pre>

<p>このスクリプトは以下のように表示します。</p>

<pre>o.p changed from 1 to 2
o.p changed from 2 to 3
o.p changed from undefined to 4
</pre>

<h3 id="Using_watch_to_validate_an_objects_properties" name="Using_watch_to_validate_an_objects_properties">watch() を使用してオブジェクトのプロパティを検証する</h3>

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

<pre class="brush: js">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' &amp;&amp; (!newval || newval.length &gt; 30)) {
      throw new RangeError('invalid name for ' + this);
    }
    if (id === 'age'  &amp;&amp; (newval &lt; 0 || newval &gt; 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);
}
</pre>

<p>このスクリプトは以下のように表示します。</p>

<pre>Will, 29
RangeError: invalid name for Will, 29
RangeError: invalid age for Will, 29
</pre>

<h2 id="Specifications" name="Specifications">仕様書</h2>

<p>どの標準にも含まれていません。</p>

<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザー実装状況</h2>

<div>どこでも対応されていません。歴史的には Firefox 1 から 57 が対応していました。</div>

<h2 id="Compatibility_notes" name="Compatibility_notes">互換性情報</h2>

<ul>
 <li>この <a class="external link-https" href="https://gist.github.com/384583">Polyfill</a> は、すべての ES5 互換ブラウザーに <code>watch</code> をもたらします。</li>
 <li>{{jsxref("Proxy")}} を使用すると、プロパティの代入操作をさらに深く変更できます。</li>
 <li>Firefox 23 より、 {{domxref("Document")}} オブジェクトで <code>watch()</code> を呼び出すと {{jsxref("TypeError")}} が発生します (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=903332">bug 903332</a>)。このリグレッションは Firefox 27 で修正しました。</li>
</ul>

<h2 id="See_also" name="See_also">関連情報</h2>

<ul>
 <li>{{jsxref("Object.unwatch()")}}</li>
 <li>{{jsxref("Object.observe()")}}</li>
</ul>