ES6中的 Proxy 和 Reflect

    xiaoxiao2022-07-03  106

    Proxy

    含义

    在目标对象之前架设一层 拦截 ,访问该对象时必须经过这层拦截,对外界的访问进行过滤和改写

    let obj = new Proxy( {}, { get: function(target, key, receiver) { console.log(`get ${key}`); return Reflect.get(target, key, receiver); }, set: function(target, key, value, receiver) { console.log(`set ${key}`); return Reflect.set(target, key, value, receiver); } } ); obj.count = 1; // set count ++obj.count; // get count set count

    api

    var proxy = new Proxy(target, handler);

    target : 所要拦截的目标对象

    handler : 定制拦截操作

    支持 13 个拦截操作

    set、get、has、deleteProperty、apply、construct …

    具体参考:http://es6.ruanyifeng.com/#docs/proxy#Proxy-实例的方法

    Proxy.revocable()

    Proxy.revocable() 返回一个可取消的 Proxy 实例

    // revoke: 取消 Proxy 实例 let { proxy, revoke } = Proxy.revocable({}, {}); proxy.foo = 123; proxy.foo; // 123 revoke(); proxy.foo; // TypeError: Revoked

    当执行 revoke 函数之后,再访问 Proxy 实例,就会抛出一个错误。

    this 问题

    在 Proxy 代理的情况下,目标对象内部的 this 关键字会指向 Proxy 代理。

    let target = { m: function() { console.log(this === proxy); } }; let handler = {}; let proxy = new Proxy(target, handler); target.m(); // false proxy.m(); // true

    web 服务的客户端

    Proxy 对象可以拦截目标对象的任意属性,这使得它很合适用来写 Web 服务的客户端:

    const service = createWebService("http://example.com/data"); service.employees().then(json => { const employees = JSON.parse(json); // ··· });

    尝尽:Proxy 可以拦截 service 对象的任意属性,所以不用为每一种数据写一个适配方法,只要写一个 Proxy 拦截就可以了。

    function createWebService(baseUrl) { return new Proxy( {}, { get(target, propKey, receiver) { return () => httpGet(baseUrl + "/" + propKey); } } ); }

    使用 Proxy 实现观察者模式

    观察者模式 :函数自动观察数据对象,一旦数据发生变化,函数就会自动执行

    // person 观察目标 const person = observable({ name: "kk", age: 12 }); // print 观察者 function print() { console.log(`打印:姓名 ${person.name}, 年龄 ${person.age}`); } observe(print); person.name = "lisi";

    使用 Proxy 写一个观察者模式的最简单实现,即实现 observable 和 observe 这两个函数。

    思路:observable 函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数

    const queuedObservers = new Set(); const observe = fn => queuedObservers.add(fn); const observable = obj => new Proxy(obj, { set }); function set(target, key, value, receiver) { // 拦截赋值操作 const result = Reflect.set(target, key, value, receiver); // 触发各个观察者 queuedObservers.forEach(observer => observer()); return result; }

    Reflect

    作用

    从 Reflect 对象上拿语言内部的方法

    修改某些 Object 方法的返回结果

    比如:在无法定义属性时,Object 会抛出一个错误,Reflect 会返回 false

    让 Object 命令式操作都变成函数行为

    // 老写法 "assign" in Object; // true // 新写法 Reflect.has(Object, "assign"); // true

    Reflect 对象的方法与 Proxy 对象的方法一一对应

    Reflect 对象的 13 个静态方法

    get、set、has、deleteProperty、apply、construct …

    具体参考:http://es6.ruanyifeng.com/#docs/reflect#静态方法

    最新回复(0)