基础认识
Proxy是ES6新提出来的内置对象,主要目的是实现在对象进行操作时能够对对象的行为进行拦截,然后拦截者可以根据自己的意愿重新定义该对象的此次操作行为。
Proxy对象用于定义基本操作的自定义行为(例如属性查找,赋值,枚举,函数调用等)
当对象或者函数进行一些行为时我们可以通过proxy对象对其行为进行拦截,而对象本身的行为就无效了
而跟Proxy对象息息相关的就是一个handler对象
基础使用
下面的代码创建一个Proxy对象p,关联对象是o,并对p的读取属性的操作进行拦截
// 创建测试对象
var o = {
a:1
}
// 创建一个proxy对象(被关联的对象,handler对象)
var p = new Proxy(o,{
// target 关联对象
// 被读取的属性名
// 当前的proxy对象
get:function(target,prop,proxy){
console.log(target,prop,proxy);
return target[prop];
}
})
// 打印 1
// 读取p的a属性行为会触发刚刚定义该proxy中handler对象的get方法,而之前对象的读取属性的行为将会被取消
// 还会打印对象o,"a",p(当前触发该行为的proxy对象)
console.log(p.a)
// 而target对象的读取行为则不会触发handler对象中的get方法
console.log(o.a)
handler对象
handler对象是proxy对象功能实现的核心模块,主要是定义当进行拦截操作后应该去做什么。handler对象可拦截的操作很多,在这里主要讲几种常见的。
1. 拦截对象读取属性的行为 handler.get
handler.set,该方法用于拦截对象的读取属性操作,刚刚上面已有演示,这里就不演示了。
2. 拦截对象设置设置属性的行为 handler.set
handler.set,该方法用于拦截设置属性值的操作
// 创建测试对象o
var o = {
a:1
}
// 创建代理对象p
let p = new Proxy(o,{
set:function(target,prop,value,proxy){
console.log(target,prop,value,proxy);
target[prop] = value;
}
})
// 为对象添加属性b
// 该行为会触发hander.set方法
// 会打印当前p关联的对象,此时添加的属性名,属性值和对象p
// {a: 1} "b" 2 Proxy {a: 1}
p.b = 2;
// Proxy {a: 1, b: 2}
console.log(p);
// {a: 1, b: 2}
console.log(o);
3. 拦截函数调用的行为 handler.apply
handler.apply,该用于拦截函数的调用。而之前的函数行为就不会发生,需要在拦截处理中手动调用该函数
// 创建测试函数
function f(){
console.log("hello world");
}
// 创建测试Proxy对象p
let p = new Proxy(f,{
// 该函数会返回三个回调参数
// target 关联的函数
// thisArg 当前执行p的this值
// args 当前执行p所传来的参数
apply:function(f,thisArg,args){
// 输出
console.log(f.prototype,thisArg,args);