简介
JavaScript的proxy是一种对象,可以用来创建一个原始对象的代理,从而实现对基本操作的拦截和自定义,如属性查找、赋值、枚举、函数调用等
例子
let person = {name: "tim", age: 3}
let pproxy = new Proxy(person, {
get: function (target, prop) {
//target有prop这个属性就返回它的值,否则返回0
return prop in target ? target[prop] : 0;
}
})
console.log(pproxy.name);
console.log(pproxy.email);
output
tim
0
pproxy 就是图中的proxyUser, 对user的所有操作又要经过proxyUser,例子中对person 的操作都要交经过pproxy(但是我的person在外面啊,可以篡改啊! 伏笔),
为什么
let proxy = new Proxy(target,handle)
实例化一个Proxy对象,这个对象的target是我们要代理的对象, 也可以说我们要保护的对象,handle(捕获器)用来拦截和修改目标对象的操作的函数.
let person = {name: "tim", age: 3}
let pproxy = new Proxy(person, {
get: function (target, prop) {
return prop in target ? target[prop] : 0;
}, // 捕获器之间加 ,
set(target, prop, value) {
if (prop === "age") {
if (!(age >= 0 && age <= 100)) {
return false
}
target[age] = value
console.log(target[prop])
return true //set 捕获器需要return bool,判断是否赋值成功
}
}
})
person.age = 34 // 未经过代理,篡改person
console.log(person.age);
console.log(pproxy.age);
output:
34
34
由于person在外面, 可以直接篡改,故将person写到proxy里的target
let pproxy = new Proxy({name: "tim", age: 3}, {})
现在pproxy代理的是一个匿名的对象,外部无法访问
篡改
let person = {age: 19}
function proxy({data}) {
let value = data.age //记下n 的值
//此时person的age已经被删除了, 访问age通过getter setter
Object.defineProperty(data, 'age', {
get() {
return value
},
set(newValue) {
if (newValue > 10) {
value = newValue;
return true
} else
return 0
},
})
//代理对象
let obj = {}
Object.defineProperty(obj, 'age', {
get() {
return data.age
},
set(newValue) {
data.age = newValue
}
})
return obj
}
let obj = proxy({data: person})
person.age = 9
console.log(person.age)
person.age = -99
console.log(person.age)
person.age = 99
console.log(person.age)
console.log("---------------")
obj.age = -99
console.log(obj.age)
obj.age = 99999
console.log(obj.age)
output:
19 //直接访问person 修改数据失败,不符合setter
19 //直接访问person 修改数据失败,不符合setter
99
---------------
99 // 代理的值不符合setter 被拦截了,修改失败
99999
此时不可以直接通过person.age直接修改值, 我们将age 提取出来,此时添加defineProperty
, 此时的age只能通过里面的setter 和getter 访问