proxy主要作用是在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过这层拦截的处理和过滤
var proxy=new Proxy(target,handle)
target表示要拦截的目标对象 handle也是一个对象,用来定制拦截行为
let target={
name:'my name'
}
var handle={
get(target,key){
console.log(`${key}被读取`)
return target[key]
},
set(target,key,value){
console.log(`${key}被设置为${value}`)
target[key]=value
}
}
var obj=new Proxy(target,handle)
console.log(obj.name)
obj.name="new name"
console.log(obj.name)
console.log(target.name)
obj.name读取属性的值时,实际上执行的是handle.get,获取被代理对象target的name属性
obj.name="new name"设置值时,实际上执行的是handle.set,设置被代理对象target的属性的值
proxy会改变代理对象target中的this指向,一旦proxy代理了target,target内部的this则指向了proxy,而不是target
const target={
get(){
console.log(this)
}
}
const p=new Proxy(target,{})
target.get()//指向的是target
p.get()//指向的是proxy
Proxy使用场景
1、实现私有变量
let person={
name:'张三',
__age:'28'
}
console.log(person.name)//28
let handle={
get(target,key){
if(key.startsWith('__')){
return '私有变量不允许访问'
}else{
return target[key]
}
},
set(target,key,value){
if(key.startsWith('__'){
return '私有变量不允许被修改'
}
}
}
let p=new Proxy(person,handle)
p.name//张三
p.__age//不允许访问
person.name
person.__age
p.__age=18//私有变量不允许被修改
比如在api对象中定义的key只允许对象内部的方法调用,但是不希望在外部也能访问api.key
var api={
key:'123abcd',
name:'my name',
getUser(){
console.log('user '+key)
}
}
console.log(api.key)//123abcd
api=new Proxy(api,{
get(target,key){
if(key=='key'){
return 'key不允许在外部访问'
}else{
return target[key]
}
},
set(target,key,value){
if(key=='key'){
return 'key不允许改变'
}else{
target[key]=value
}
}
})