Proxy
{ let obj = { time: '2019-11-08', name: 'Helzeo', _r: 858511254 } let monitor = new Proxy(obj, { // 拦截对象属性的读取, 把要读取数据的 key 的值含有 2019 的 替换成 2020 get(target, key) { // target 便是当前代理对象, key 是访问的 k 值 return target[key].replace('2019', '2020') }, // 拦截对象设置属性 set(target, key, value) { if (key === 'name') { // key 为 name 的才允许修改 return target[key] = value } else { return target[key] } }, // 判断当前对象是否拥有某个属性 (拦截 key in Object 操作) has(target, key) { if (key === 'name') { return target[key] } else { return } }, // 代理拦截删除 (拦截 delete key 操作) deleteProperty(target, key) { if (key.indexOf('_') > -1) { delete target[key] return true } else { return target[key] } }, // 拦截遍历 (Object.keys, Object.getOwnPropertySymbol, Object.getOwnPropertyNames) ownKeys(target) { return Object.keys(target).filter(item => item != 'time') } }) console.log(monitor.time) // 2020-11-08 monitor.time = '2021' monitor.name = 'HelzeoLee' console.log(monitor.time) // 2020-11-08 console.log(monitor.name) // HelzeoLee console.log('_r' in monitor) // false 被拦截 console.log('name' in monitor) // true 开放拦截 delete monitor.time delete monitor._r console.log(monitor) // {time: "2019-11-08", name: "HelzeoLee"} _r被删掉了 console.log('ownKeys', Object.keys(monitor)) // ["name"] _r 被删除了, time 被保护了 }
Reflect
reflect 直接使用, 不需要 new, reflect 的使用和 proxy 几乎一样
{ let obj = { time: '2019-11-08', name: 'Helzeo', _r: 858511254 } // 读 console.log(Reflect.get(obj, 'time')) // 2019-11-08 // 改 Reflect.set(obj, name, 'HelzeoLee') console.log(obj.name) // HelzeoLee // 检测属性 console.log(Reflect.has(obj, name)) // true }
使用场景-Proxy 和 Reflect 实现表单验证(和业务解耦)
{ function validator(target, validator) { return new Proxy(target, { _validator: validator, set(target, key, value, proxy) { if (target.hasOwnProperty(key)) { let va = this._validator[key] if (va(value)) { return Reflect.set(target, key, value, proxy) } else { throw Error(`不能设置${key}为${value}`) } } else { throw Error(`${key}, 是不存在的`) } } }) } // 设置校验条件 const personValidators = { name(val) { return typeof val === 'string' }, age(val) { return typeof 'number' && val > 18 } } class Person { constructor(name, age){ this.name = name this.age = age return validator(this, personValidators) } } const person = new Person('Helzeo', 30) console.log(person) person.name = 55 // 报错 console.log(person) }
以上代码的好处就是条件和业务本身完全隔离开, 便于维护, 代码简洁, 可维护性复用性强