Object.prototype.watch()

翻译不完整。 请帮助我们翻译这篇文章!

警告: 通常来讲,你应该尽量避免使用 watch()和  unwatch() 这两个方法。因为只有 Gecko 实现了这两个方法,并且它们主要是为了在调试方便。另外,使用 watchpoint 对性能有严重的负面影响,在全局对象(如 window)上使用时尤其如此。你可以使用 setters and getters 或者 proxy 代替。参见 Compatibility 了解详情。

watch() 方法会监视属性是否被赋值并在赋值时运行相关函数。

语法

obj.watch(prop, handler)

参数

prop
想要监视值是否发生变化的指定对象的某个属性的属性名称
handler
当指定的属性发生变化时执行的回调函数

返回值

undefined.

描述

监视对指定对象的名为 prop 属性的赋值操作,只要 prop 属性被赋值,便调用 handler(prop, oldval, newval) 回调函数,并将函数返回值保存到该属性。 通过返回修改的新值(或者返回旧值),一个监视点可以过滤(或使之为 null )赋值。

如果你删除某个设置监视点的属性,该监视点并不会消失。如果你之后重新创建这个属性,监视点仍然有效。

要移除某个监视点,使用 unwatch() 方法。默认所有 Object 的后代都将继承 watch 方法。

JavaScript 调试器有与之相似的机制以及其它调试选项。需要更多有关调试器的信息,请查阅 Venkman

对于 Firefox,handler 只会被脚本内的赋值操作激活,并不包括本地代码。举个例子,如果用户点击一个指向当前文档内的某个锚点, window.watch('location', myHandler) 不会回调 myHandler ,但 window.location += '#myAnchor' 将触发回调  myHandler

注意: 对一个对象的指定属性调用 watch()  将覆盖先前关联的 handler。

例子

使用 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 来检测一个对象的属性赋值是否是合法的.下例演示了如何确保每个人始终具有一个合法的名字和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("不合法的名字 " + this);
  }
  if (id === "age"  && (newval < 0 || newval > 200)) {
    throw new RangeError("不合法的年龄 " + this);
  }
  return newval;
}

will = new Person("Will", 29);
print(will);   // Will, 29

try {
  will.name = "";
} catch (e) {
  //print(e);
  console.log(e);
}

try {
  will.age = -4;
} catch (e) {
  console.log(e);
}

上面的代码显示结果如下:

Will, 29
RangeError: 不合法的名字 Will, 29
RangeError: 不合法的年龄 Will, 29

Specifications

不是任何规范的一部分。从 JavaScript 1.2 开始实现。

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 未实现 (Yes) 未实现 未实现 未实现
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support 未实现 未实现 (Yes) 未实现 未实现 未实现

兼容性提示

  • 此 Polyfill 为所有 ES5 兼容浏览器提供 watch 支持。
  • 使用 Proxy 允许你更加深度地调整属性服务机制
  • 从 Firefox 23 开始,在 Document 对象上调用 watch() 将抛出 TypeError 错误。这个回归问题已经在 Firefox 27 修复。

相关链接