Deprecation warning:
Do not use
watch()
and
unwatch()
! These two methods were implemented only in Firefox prior to version 58, they're
deprecated and removed in Firefox 58+
. In addition, using watchpoints has a serious negative impact on performance, which is especially true when used on global objects, such as
window
. You can usually use
setters and getters
or
proxies
代替。
watch()
method watches for a property to be assigned a value and runs a function when that occurs.
obj.watch(prop, handler)
prop
The name of a property of the object on which you wish to monitor changes.
handler
A function to call when the specified property's value changes.
Watches for assignment to a property named
prop
in this object, calling
handler(prop, oldval, newval)
whenever
prop
is set and storing the return value in that property. A watchpoint can filter (or nullify) the value assignment, by returning a modified
newval
(or by returning
oldval
).
If you delete a property for which a watchpoint has been set, that watchpoint does not disappear. If you later recreate the property, the watchpoint is still in effect.
To remove a watchpoint, use the
unwatch()
method. By default, the
watch
method is inherited by every object descended from
Object
.
The JavaScript debugger has functionality similar to that provided by this method, as well as other debugging options. For information on the debugger, see Venkman .
In Firefox,
handler
is only called from assignments in script, not from native code. For example,
window.watch('location', myHandler)
will not call
myHandler
if the user clicks a link to an anchor within the current document. However,
window.location += '#myAnchor'
will call
myHandler
.
注意:
调用
watch()
on an object for a specific property overrides any previous handler attached for that property.
watch
and
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;
This script displays the following:
o.p changed from 1 to 2 o.p changed from 2 to 3 o.p changed from undefined to 4
可以使用
watch
to test any assignment to an object's properties. This example ensures that every Person always has a valid name and an age between 0 and 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);
}
This script displays the following:
Will, 29 RangeError: invalid name for Will, 29 RangeError: invalid age for Will, 29
Not part of any standard.
watch
to all ES5 compatible browsers.
Proxy
enables you do even deeper changes to how property assignments work.
watch()
on the
Document
object throws a
TypeError
since Firefox 23 (
bug 903332
). This regression has been fixed with Firefox 27.
Archive
Function
Object
Object.prototype.__defineGetter__()
Object.prototype.__defineSetter__()
Object.prototype.__lookupGetter__()
Object.prototype.__lookupSetter__()
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()
Object.prototype.toLocaleString()
Object.prototype.toSource()
Object.prototype.toString()
Object.prototype.valueOf()
Object.setPrototypeOf()