前言
在完成仿写任务时,用其来检测变量的改变,故借此总结学习一下
概念
Proxy 可以拦截并自定义对某个对象的基本操作
语法如下
const name = new Proxy(target, handler);
target
:要被代理的对象
handler
:拦截器对象,里面放有“陷阱函数”
通过
name
访问target
时若此次操作行为在拦截器对象中存在对应的陷阱函数,那么此次操作将根据拦截器中对应的函数来触发
通过target直接访问原对象则不会触发
如下可以拦截数组的增加和删除功能
const arr=[1,2,3,4,5,6,7,8]
const role=new Proxy(arr,{
set(target, property, value){//对于数组操作 改值和改length都会触发,但我们的自定义方法仅需调用一次故
console.log('在外部故触发俩次');
if (property === 'length') {//只有当改length时才触发
console.log('准备修改length');
}
let a=Reflect.set(target, property, value)//此方法就是进行此次操作赋值类似target[property]=value//返回值是是否成功完成此次赋值 成功为true反之
//在此之后赋值已经完成了
// 直到
return a//陷阱函数也需要返回布尔值来确认此次方法是否成功
}
,
deleteProperty(target, property){//此方法只会在调用delete关键字才会触发
console.log('准备删除');
let result=Reflect.deleteProperty(...arguments);
}
})
console.log(arr.length);
delete role[2]//触发自定义的删除,但delete只是释放了对应的地址
// 还需要
role.push(9)
console.log(arr.length);
arr.splice(2,1)//来删除
console.log(arr.length);
console.log(arr);
控制台如图
陷阱函数
set
上述的set只拦截 赋值 操作
故role.push(9)
有俩次拦截,第一次是对数组扩充赋值的拦截
第二次则是给length赋予新值而被拦截deleteProperty
deleteProperty只拦截删除操作
如上get
拦截读取操作
//加入
,get(target, property){
console.log('拦截读取');
Reflect.get(...arguments);
}
//调用
console.log(role[2])
结果
总结
- 陷阱函数需要返回布尔值来判断此次操作是否成功
可以调用Reflect.对应函数(...arguments)
来进行赋值
在此之前操作属于拦截状态未执行,反之 - set拦截的是赋值操作,对数组进行赋值会有俩次拦截
分别是length
赋值和扩充数组
- 使用