JS object watch()

🌙
手机阅读
本文目录结构

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

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

语法

obj.watch(prop, handler)

参数

prop

想要监视值是否发生变化的指定对象的某个属性的属性名称

handler

当指定的属性发生变化时执行的回调函数

返回值

undefined.

描述

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.

注意: Calling watch() on an object for a specific property overrides and previous handler attached for that property.

例子

使用 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

Not part of any specifications. Implemented in JavaScript 1.2.

兼容性提示

  • This Polyfill offers watch to all ES5 compatible browsers.
  • Using a Proxy enables you do even deeper changes to how property assignments work.
  • Calling watch() on the Document object throws a TypeError since Firefox 23 (bug 903332). This regression has been fixed with Firefox 27.

相关链接

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了