1、概述
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,就是对语言层面上的逻辑进行的修改
Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
2、基本使用
let obj = {
a:100,
b:200,
c:300
}
let proxyObj = new Proxy(obj,{
get:function(){
return "获取值的内容"
},
set:function () {
console.log("设置的内容")
}
})
console.log(proxyObj.c)
proxyObj.c = 666
console.log(proxyObj)
上面的proxyObj是设置可以拦截的对象,第一个拦截obj参数是对应要拦截的对象内容,第二个参数是拦截行为,所有的行为在一个对象中
行为的内部可以设置参数
let obj = {
a:100,
b:200,
c:300
}
let proxyObj = new Proxy(obj,{
get:function(target,key){
return `拦截目标${target} ,拦截属性${key} ,拦截目标属性的值${target[key]}`
},
set:function (target,key,value) {
console.log(`设置目标${target} ,设置属性${key} ,设置目标属性的值${value}`)
}
})
console.log(proxyObj.b)
proxyObj.c = 666
console.log(proxyObj)
get方法主要的参数有两个,第一个target指的目标对象,key表示获取的该对象的key
set方法主要的参数有三个,第一个target指的目标对象,key表示获取的该对象的key,value表示要设置的value
3、Proxy可以当做原型对象
let proxy = new Proxy({},{
get:function () {
return 35
},
set:function () {
}
})
let obj = Object.create(proxy)
console.log(obj.time) 35
4、get方法
get方法用于拦截某个属性的读取操作
let person = {
name:"小明",
age:"19岁"
}
let proxy = new Proxy(person,{
get:function (target,property) {
// 判断当前的key是否在对应的对象上,也就是查询对象上有没有要查的这个key
if(property in target){
///如果有就返回这个值
return target[property]
}else{
//没有则抛出错误
throw new ReferenceError("Property \"" + property + "\" does not exist.");
}
}
})
console.log(proxy.name)// 小明
console.log(proxy.age)// 19岁
//console.log(proxy.aaa) 报错
get方法内部有三个参数 第一个target表示接受对象,第二个是获取的key,第三个表示操作对象receiver(不常用)
5、set方法
set方法用来拦截某个属性的赋值操作
比如假定Person对象有一个age属性,该属性应该是一个不大于200的整数,那么可以使用Proxy保证age的属性值符合要求
let validator = {
set : function (obj,prop,value) {
//isInteger 整数
if(!Number.isInteger(value)){
throw new TypeError('The age is not an integer');
}
if(value > 200){
throw new RangeError('The age seems invalid');
}
obj[prop] = value;
}
}
let person = new Proxy({},validator);
console.log(person.age = 100);//100
console.log(person.age = 400);//报错
set方法一共有4个参数,第一个参数是接受的对象,第二个参数是设置的key,第三个是设置值,第四个参数是操作对象receiver(不常用)
6、apply 方法 **********?????
方法拦截函数的调用、call和apply操作
var twice = {
apply(target, ctx, args) {
// Reflect.apply(...arguments)返回是对参数的累加结果
return Reflect.apply(...arguments) * 2;
}
};
function sum(left, right) {
// 累加
return left + right;
};
var proxy = new Proxy(sum, twice);
proxy(1, 2) // 6
proxy.call(null, 5, 6) // 22
proxy.apply(null, [7, 8]) // 30
7、construct方法
construct方法用于拦截new命令
var p = new Proxy(function() {}, {
construct: function(target, args) {
console.log('called: ' + args.join(', '));
return { value: args[0] * 10 };
}
});
console.log(new p(1).value)
construct方法返回的必须是一个对象,否则会报错