用过vue的知道,vue的响应实现用的Proxy,且里面是配合Reflect用的,查看Proxy和Reflect文档最显眼的是Reflect对象的静态方法和Proxy代理方法的命名相同,Reflect可以操作对象使用, proxy可以代理对象,但没有找到为啥有时一定要在Proxy代理方法中使用Reflect
Object -> Reflect
let obj = {}
let newVal = ''
Reflect.defineProperty(obj, 'name', {
get(){
console.log('get')
return newVal
},
set(){
console.log('set')
newVal = val
}
})
obj.name = 'es'
console.log(obj.name)
try{
Object.defineProperty()
} catch(e) {
}
修改某些Object方法的返回结果,让其变得更合理
if(Reflect.defineProperty()){ // boolean
}else{
}
让Object操作变成函数行为
console.log('assign' in Object) //true
console.log(Reflect.has(Object, 'assign')) // true
Reflect对象的方法与Proxy 对象的方法一一对应
let user = {
name: 'UU',
age: 4,
_password: '***'
}
user = new Proxy(user, {
get(target, prop) {
if(prop.startsWith('_')){
throw new Error('不可访问')
} else {
return Reflect.get(target, prop)
}
},
set(target, prop, val){
if(prop.startsWith('_')){
throw new Error('不可访问')
} else {
Reflect.set(target, prop, val)
return true
}
}
deleteProperty(){ // 删除拦截
if(prop.startsWith('_')){
throw new Error('不可删除')
} else {
Reflect.defineProperty(target, prop)
return true
}
},
ownKeys(target) {
return Reflect.ownKeys(target).filter(key => !key.startsWith('_'))
}
})
console.log(user.age)
try{
console.log(user._password)
}catch(e){
console.log(e.message)
}
user.age = 18
console.log(user.age)
try{
user._password = 'xxx'
}catch(e){
console.log(e.message)
}
delete user.age
console.log(user.age)
for(let key in user){
console.log(user)
}
apply
let sum = (...args) => {
let num = 0
args.forEach(item => {
num += item
})
return num
}
sum = new Proxy(sum, {
apply(target, ctx, args) {
return Reflect.apply(target, target, [...args]) * 2
}
})
console.log(sum(1, 2)) // 6
console.log(sum(null, 1, 2, 3)) // 12
console.log(sum.apply(null, [1, 2, 3])) // 12