MDN给出的定义是: proxy对象用于定义基本操作的自定义行为, 例如属性查找, 赋值, 枚举, 函数调用等
proxy
捕获对其目标对象
进行的调用和操作, 然后可以更优雅的处理这些调用和操作, 它在目标对象
周围创建了一个无法检测的屏障, 将所有操作重定向到处理程序对象
基本用法
代理使用new Proxy()
来创建, 该构造函数接受两个必要的参数: 目标对象target
和处理程序对象handler
let target = {} let handler = { // target操作的处理方法 } let proxyObject = new Proxy(target, handler)
@理解:
proxy相当于一个黑匣子, 封装对目标对象的处理, proxy的实例对象相当于对外暴露的接口,外部人员对目标对象的操作不再直接作用于目标对象, 而是通过proxy实例对象重定向到proxy内部的处理方法上(像get set等) , 最后再将处理后的最终结果返回给proxy实例
这些代理方法其实就是proxy对原生方法的监听, 然后用内部对应的方法去处理
可以接收三个参数: 目标对象、属性名、[ proxy实例 ]
get方法可以看作是对目标对象
取
操作的代理
let target = { id: 100 } let handler = { get: function (target, prop) { if (target.hasOwnProperty(prop)) { return target[prop] } } } let proxy = new Proxy(target, handler) console.log(proxy.id)
可以接收四个参数: 目标对象, 属性名, 属性值, [ proxy实例 ]
set方法可以看作是对目标对象某个属性的赋值代理
let target = { id: 100 } let handler = { set: function (target, prop, value) { if (value > 500) { console.log('超出最大值'); } else { target[prop] = value } } } let proxy = new Proxy(target, handler) proxy.id = 600 // 超出最大值 proxy.name = '猫13' proxy.id = 200 console.log(proxy.id) // 200 console.log(proxy.name) // 猫13
接收两个参数: 目标对象, 待删除的属性名
相当于delete obj.prop
let person = { usr1: [1, { name: '猫13' }], usr2: [2, { name: '猫14' }], } // 之前删除是这样的 // delete person.name 下面用Proxy来拦截 var handler = { deleteProperty(target, key) { if (target[key][0] === 1) { console.log('usr1不能被删除'); } else { delete target[key] } } }; let proxy = new Proxy(person, handler); delete proxy.usr1 // usr1不能被删除 delete proxy.usr2 console.log(proxy) // Proxy {usr1: Array(2)}
该方法主要用于拦截函数的调用
接受的第一个参数是目标函数
let t1 = function () { console.log('hi'); } let handler = { apply: function (sayHi) { console.log(`你的${t1.name}方法被拦截了`) } } let proxy = new Proxy(target, handler) proxy() // 你的t1方法被拦截了
has()
方法是针对 in
操作符的代理方法
接收两个参数: 目标对像, 属性名
let target = { iid: 100, uid: 200 } let handler = { has: function (target, prop) { if (prop[0] === 'i') { return false } return prop in target } } let proxy = new Proxy(target, handler) console.log('iid' in proxy); // false console.log('uid' in proxy); // true
Proxy - 更多方法参考MDN
个人理解: reflect将proxy代理方法的内部处理做了封装, 简化了操作步骤
另外: proxy有的代理方法, reflect也有
简单看一下
let target = {} let handler = { set: function (target, prop, value) { // 之前我们这样赋值 // target[prop] = value // 使用reflect可以这样 Reflect.set(target, prop, value) } } let proxy = new Proxy(target, handler) proxy.name = "猫13" console.log(proxy.name) // 猫13