ES6 Proxy
一、proxy概述
二、Proxy所能代理的范围--handle
r三、Proxy场景
3.1 实现私有变量
3.2 抽离校验模块
3.3 访问日志
3.4 预警和拦截
3.5 过滤操作
3.6 中断代理
四、Reflect
五、Proxy和Object.defineProperty的对比
一、proxy概述
Proxy的兼容性
image.png
proxy
在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过这层拦截。
var proxy = new Proxy(target, handler);
new Proxy()
表示生成一个Proxy
实例,target
参数表示所要拦截的目标对象,handler
参数也是一个对象,用来定制拦截行为
var target = { name: 'poetries' }; var logHandler = { get: function(target, key) { console.log(`${key} 被读取`); return target[key]; }, set: function(target, key, value) { console.log(`${key} 被设置为 ${value}`); target[key] = value; } } var targetWithLog = new Proxy(target, logHandler); targetWithLog.name; // 控制台输出:name 被读取 targetWithLog.name = 'others'; // 控制台输出:name 被设置为 others console.log(target.name); // 控制台输出: others
-
targetWithLog
读取属性的值时,实际上执行的是logHandler.get
:在控制台输出信息,并且读取被代理对象target
的属性。 -
在
targetWithLog
设置属性值时,实际上执行的是logHandler.set
:在控制台输出信息,并且设置被代理对象target
的属性的值
// 由于拦截函数总是返回35,所以访问任何属性都得到35 var proxy = new Proxy({}, { get: function(target, property) { return 35; } }); proxy.time // 35 proxy.name // 35 proxy.title // 35
Proxy 实例也可以作为其他对象的原型对象
var proxy = new Proxy({}, { get: function(target, property) { return 35; } }); let obj = Object.create(proxy); obj.time // 35
proxy
对象是obj
对象的原型,obj
对象本身并没有time
属性,所以根据原型链,会在proxy
对象上读取该属性,导致被拦截
Proxy的作用
对于代理模式
Proxy
的作用主要体现在三个方面
-
拦截和监视外部对对象的访问
-
降低函数或类的复杂度
-
在复杂操作前对操作进行校验或对所需资源进行管理
二、Proxy所能代理的范围--handler
实际上
handler
本身就是ES6
所新设计的一个对象.它的作用就是用来 自定义代理对象的各种可代理操作 。它本身一共有13
中方法,每种方法都可以代理一种操作.其13
种方法如下
// 在读取代理对象的原型时触发该操作,比如在执行 Object.getPrototypeOf(proxy) 时。 handler.getPrototypeOf() // 在设置代理对象的原型时触发该操作,比如在执行 Object.setPrototypeOf(proxy, null) 时。 handler.setPrototypeOf() // 在判断一个代理对象是否是可扩展时触发该操作,比如在执行 Object.isExtensible(proxy) 时。 handler.isExtensible() // 在让一个代理对象不可扩展时触发该操作,比如在执行 Object.preventExtensions(proxy) 时。 handler.preventExtensions() // 在获取代理对象某个属性的属性描述时触发该操作,比如在执行 Object.getOwnPropertyDescriptor(proxy, "foo") 时。 handler.getOwnPropertyDescriptor() // 在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 Object.defineProperty(proxy, "foo", {}) 时。 andler.defineProperty() // 在判断代理对象是否拥有某个属性时触发该操作,比如在执行 "foo"