JavaScript数据代理Proxy

93 阅读2分钟

Proxy

概念

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

 const p = new Proxy(target, handler)

target

要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler

以函数作为属性的对象,在函数内部定义了在执行各种操作时的逻辑。

handler对象的方法

  1. handler.construct()new 操作符的捕捉器

    在new Proxy对象时调用

  2. handler.get()属性读取操作的捕捉器

    获取属性值时调用

  3. handler.set()属性设置操作的捕捉器

    属性被赋值时调用

还有很多方法

handler.get()

get 方法可以返回任何值。

访问属性:proxy[foo] 和 proxy.bar

如果要访问的目标属性没有配置访问方法,即 get 方法是 undefined 的,则返回值必须为 undefined。

 // 新建代理对象p,当该对象不存在属性名时,返回‘属性不存在’
 const p = new Proxy({}, handler);
 const handler = {
     get: function(target, prop, receiver ) {
         return property in target ? target[property] : 37;
     }
 };
 ​
 p.a = 1;
 p.b = undefined;
 ​
 console.log(p.a, p.b);      // 1, undefined
 console.log('c' in p, p.c); // false, 属性不存在

target

目标对象。

property

被获取的属性名。

receiver

Proxy 或者继承 Proxy 的对象

handler.set()

set() 方法返回一个布尔值

返回 true 代表属性设置成功

若目标属性是一个不可写及不可配置的数据属性,则不能改变它的值。

如果目标属性没有配置存储方法,即 [[Set]] 属性的是 undefined,则不能设置它的值。

在严格模式下,如果 set() 方法返回 false,那么会抛出一个 TypeError 异常

 const handler = {
    set: function(target, property, value, receiver) {
   }
 };
 ​
 const p = new Proxy(target, handler);

target

目标对象。

property

将被设置的属性名或 Symbol

value

新属性值。

receiver

最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。

 obj.name = "cx"
 // 假设obj不是Proxy,但是它的原型链上有一个 proxy;
 // 此时执行了obj.name = "cx"的代码,原型链上 proxy 的 set() 处理器会被调用
 // 此时的 obj 会作为 receiver 参数传进来

最后一句

学习心得!若有不正,还望斧正。希望掘友们不要吝啬对我的建议。