Proxy
Object.definePorperty() 与 proxy 都可以监听对象的变化
但 Object.definePorperty() 进行数据监听是比较麻烦的,需要大量的手动处理。对象新增加一个属性时,也需要手动去监听这个新增属性。对于数组得监听还有一系列问题。
所以都什么时代了,还用传统数据监听方式啊,来试试
**proxy**
吧
Proxy
1. 基本使用
语法:const p = new Proxy(target, handler) 参数:
TS 定义
1 |
|
1 |
|
但是一旦使用 Proxy,如果想要读写操作生效,我们就要对 Proxy 的实例对象**proxyObj**进行操作。**proxyObj** set 后,原对象 obj 也会被 set,但原对象的 get 无法触发**handler**。
另外,MDN 上明确指出 set()方法应该返回一个布尔值,否则会报错TypeError。
2. 轻松解决 object.definePorperty() 的问题
Object.defineProperty 的问题
- 一次只能对一个属性进行监听,需要遍历来对所有属性监听。这个我们在上面已经解决了。
- 在遇到一个对象的属性还是一个对象的情况下,需要递归监听。
- 对于对象的新增属性,需要手动监听
- 对于数组通过 push、unshift 方法增加的元素,也无法监听
用了 Proxy 后可以完美解决以上问题
3. proxy 的 13 种拦截
get(target, propKey, receiver)
:拦截对象属性的读取,比如 proxy.foo 和 proxy[‘foo’]。set(target, propKey, value, receiver)
:拦截对象属性的设置,比如 proxy.foo = v 或 proxy[‘foo’] = v,返回一个布尔值。has(target, propKey)
:拦截 propKey in proxy 的操作,返回一个布尔值。deleteProperty(target, propKey)
:拦截 delete proxy[propKey]的操作,返回一个布尔值。ownKeys(target)
:拦截 Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for…in 循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys()的返回结果仅包括目标对象自身的可遍历属性。getOwnPropertyDescriptor(target, propKey)
:拦截 Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。defineProperty(target, propKey, propDesc)
:拦截 Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。preventExtensions(target)
:拦截 Object.preventExtensions(proxy),返回一个布尔值。getPrototypeOf(target)
:拦截 Object.getPrototypeOf(proxy),返回一个对象。isExtensible(target)
:拦截 Object.isExtensible(proxy),返回一个布尔值。setPrototypeOf(target, proto)
:拦截 Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。apply(target, object, args)
:拦截 Proxy 实例作为函数调用的操作,比如 proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。construct(target, args)
:拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(…args)。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!