JavaScript Proxy基本用法详解
volit_ 人气:01.语法
const proxy = new Proxy(target, handle);
- target,被代理的对象
- handle,拦截规则
2.基本用法
const obj = {}; const proxy = new Proxy(obj, { // target 目标对象;propKey 属性名;receiver 实例本身; get: function(target, propKey, receiver) { return 10; } }) console.log(proxy.a); // 10 console.log(proxy.b); // 10 console.log(obj.a); // undefined console.log(obj.b); // undefined
以上代码对obj对象的get操作进行了拦截,任何读取操作都仅会返回10,且该操作只作用在代理对象proxy上,对原对象本身是不起作用的。
ps.若obj对象是不可写及不可配置的,代理对象的返回值要与被代理对象的返回值保持一致;若被代理对象没有配置get方位方法,即get方法是undefined,那么返回值必须是undefined
handle对象的常用方法:
方法 | 描述 |
---|---|
has | in操作符捕捉器 |
get | 属性读取操作符捕捉器 |
set | 属性设置操作符读取器 |
deleteProperty | delete操作符读取器 |
ownKeys | Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。 |
apply | 函数调用捕捉器 |
construct | new操作符的捕捉器 |
3.可消除的Proxy
Proxy有一个唯一的静态方法Proxy.revocable(target, handler),可以用来创建一个可撤销的代理对象,该方法的返回值是一个对象,其结构为: {"proxy": proxy, "revoke": revoke}
。
- proxy 表示新生成的代理对象本身,和用一般方式 new Proxy(target, handler) 创建的代理对象没什么不同,只是它可以被撤销掉。
- revoke 撤销方法,调用的时候不需要加任何参数,就可以撤销掉和它一起生成的那个代理对象。
ps.该方法常用于完全封闭对目标对象的访问。
4.Vue为什么要用Proxy重构
Vue3.0之前,双向绑定主要是由defineProperty实现的。而defineProperty这个方法本身其实是存在不足的,比如说对于对象属性增加、数组按下标修改等一下操作无法做到原生实现。虽然Vue有提供相应的手动observer方法,但在使用体验上还是不尽如人意的。而想较于defineProperty针对属性进行拦截,Proxy直接劫持了整个对象,即不需要对特殊的操作做单独处理。
5.Proxy与defineProperty的对比
(1)Proxy作为新标准,浏览器支持良好
(2)Proxy能观察的类型比defineProperty
更丰富
(3)Proxy不兼容IE,也没有polyfill,defineProperty
可以支持到IE9
(4)defineProperty
劫持对象的属性,当新增属性时,需要再次defineProperty
;Proxy直接劫持整个对象,不需要额外操作。
(5)defineProperty
在原对象本身进行拦截操作,而Proxy只能在生成的拦截的对象上进行拦截操作。
加载全部内容