1.通过get设置代理对象的属性
// 原对象 let obj = { name: 'zs', age: 23 } // newObj是代理的对象 let newObj = new Proxy(obj, { // get是读取属性的方法 get(target, key) { if (key === 'age') { return target[key] + 20 } else { return target[key] } } }) console.log(newObj.age); //43 访问的是经过代理的对象,而不是原对象
2.set设置对象属性,或者禁止设置对象属性
// set 禁止设置属性,只读操作 let o = { name: 'zs', age: 12 } let newObj = new Proxy(o, { set(target, key, value) { return false // 禁止设置属性 } }) newObj.age = 30 console.log(newObj.age);// 12 赋值不生效
3.使用代理做校验
一个需求:(1)对象中的name和price属性可以访问,
(2)访问没有的属性时(例如访问了age),返回空字符串。
(3)name属性可写,不存在的属性不可写,price属性大于300时不可写
// 监听错误 window.addEventListener('error',(e)=>{ alert('错了啊') }) // 使用代理做校验 let obj = { name: 'zs', price: 190 } // 校验方法 let validator = (target, key, value) => { // 判断是否含有该属性 if (Reflect.has(target, key)) { if (key === 'price') { if (value > 300) { throw new TypeError('不能大于300') } else { return target[key] = value } } else { return target[key] = value } } else { return false } } let newObj = new Proxy(obj, { // 设置为可读,但是读取不存在的属性转换为空字符串 get(target, key) { return target[key] || '' }, set: validator }) console.log(newObj.name); // 可读 console.log(newObj.price); // 可读 console.log(newObj.age); // 没有该属性,转为空字符串 newObj.name = 'ls' console.log(newObj); // 可写 newObj.age = 120 // 不可写 console.log(newObj); // age属性设置不生效 newObj.price = 299 // 可写 console.log(obj.price); // 299 设置生效 newObj.price = 301 // 不可写 console.log(newObj.price); // 299
4.可撤销的代理
// 可撤销的代理 let o = { name: 'zs', age: 12 } let obj = Proxy.revocable(o, { get(targrt, key, value) { if (key === 'age') { return target[key] + 2 } else { return target[key] } } }) console.log(obj.Proxy.age); // 14 setTimeout(() => { obj.revoke() // 取消代理 setTimeout(() => { console.log(obj.proxy.age); // 取消代理之后,再次读取属性,报错 }, 300); }, 200);