proxy—(基础)
定义: proxy对js中的所有类型, 做一个代理, 所有操作都会先进入代理, 如果我们有设置对应操作的代理,那么优先使用我们自定义的操作(最常见是get/set).如果没有对应代理, 那么进入正常操作.
来看一下语法:
1 | // target: 被代理的目标 |
来看一下mdn上面的示例, 我们能更好的理解proxy的行为
示例1: 代理object的get方法
1 | // 初始化一个handler, 该handler的内容是设置get方法, 如果我们读取了不在该对象上的属性, 则返回默认值37 |
代理转发, 数据绑定
简而言之, proxy构造函数的第一个参数,就是被绑定的元素。当我们修改proxy生成的实例时,修改会传递到被绑定的元素上。达到数据绑定的目的.
来看例子:
1 | let target = {}; |
验证对象赋值
我觉得代理有点像钩子的概念, 当我加入代理后, 那么我可以重写原有的默认行为(get/set), 也可以在原有的get/set增加逻辑, 就时钩子的概念啊.
这个例子重写了对象的set方法, 在set方法里验证对于属性’age’的赋值是否合法.并且保留默认的set行为.达到了验证的效果.
我们在vue/react都存在对应的props数据验证.在这个地方是否就是用proxy重写的?
1 | let validator = { |
高阶应用之: 扩展构造函数
Reflect
这里要引入一个es2015的api.Reflect
Reflect是新增的一个内置对象, 这个对象不是构造函数, 无法使用new操作符,Reflect上所有的方法都是静态的.(类似Math.Refect对象)。
1 | // 例如, get方法 |
所以,其实ReflectAPI实际上是, 把Reflect作为一个静态标识, 类似Math, 然后以第一个参数为this, 去调用this上的get方法.
注意了, 如果Reflect调用时, 对象的默认行为已经被修改, 那么此时, 会触发修改后的行为.
1 | // 类似这种效果 |
到这里, 关于Reflect的基本知识就足够了.
构造函数扩展
平常,我们都是通过以下方式来完成一个构造函数的扩展, 有了proxy我们就可以用一个新姿势来处理这种场景。
1 | // 手动实现构造函数OLO |
扩展构造函数
1 | function extend(sup,base) { |
使用proxy实现双向绑定
1 | const input = document.getElementById('input'); |