zoukankan      html  css  js  c++  java
  • es6-12 Proxy 和 Reflect

    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)
    }
    以上代码的好处就是条件和业务本身完全隔离开, 便于维护, 代码简洁, 可维护性复用性强
  • 相关阅读:
    linux命令之free篇
    linux操作之逻辑分区与交换分区篇
    linux之软连接,硬连接篇
    Linux之磁盘分区篇
    Linux命令之vi篇
    JVM总结-垃圾回收算法
    JVM总结-字节码
    JVM总结-java对象的内存布局
    JVM-synchronized怎么实现的?
    JVM总结-invokedynamic
  • 原文地址:https://www.cnblogs.com/helzeo/p/11821288.html
Copyright © 2011-2022 走看看