1. Proxy
1. proxy是什么
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实例
2. 常用的代理方法
这些代理方法其实就是proxy对原生方法的监听, 然后用内部对应的方法去处理
2.1 get方法
可以接收三个参数: 目标对象、属性名、[ 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)
2.2 set方法
可以接收四个参数: 目标对象, 属性名, 属性值, [ 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
2.3 deleteProperty方法
接收两个参数: 目标对象, 待删除的属性名
相当于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)}
2.4 apply方法
该方法主要用于拦截函数的调用
接受的第一个参数是目标函数
let t1 = function () {
console.log('hi');
}
let handler = {
apply: function (sayHi) {
console.log(`你的${t1.name}方法被拦截了`)
}
}
let proxy = new Proxy(target, handler)
proxy() // 你的t1方法被拦截了
2.5 has方法
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
2. Reflect
个人理解: 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