Proxy-Reflect

监听对象的操作

使用存储属性描述符

<script>
        const obj = {
            name:'Li',
            age:18,
            gender:'man'
        }
        Object.keys(obj).forEach(key => {
            Object.defineProperty(obj, key, {
                get() {
                    console.log(`obj中的${key}的值被获取`);
                },
                set() {
                    console.log(`obj中的${key}的值被设置`);
                }
            })
        })

        console.log(obj.name);
        obj.age = 20
    script>

缺点:
与设计初衷不符
难以进行增加和删除操作的监听

proxy可以监听13种操作

proxy是一个类
实例是代理对象

使用proxy实现刚才的操作

 <script>
        const obj = {
            name:'Li',
            age:18,
            gender:'man'
        }
       
        const proxyObj = new Proxy(obj, {})
        console.log(proxyObj.name);
        console.log(proxyObj.age);

        proxyObj.age = 20
        
        console.log(obj);
        console.log(proxyObj);

    script>

Proxy-Reflect_第1张图片
确实可以通过proxyObj来操作obj

通过重写Proxy的捕获器来监听对对象的操作

<script>
        const obj = {
            name:'Li',
            age:18,
            gender:'man'
        }
       
        const proxyObj = new Proxy(obj, {
            get(target, key) {
                console.log(target,`对象的${key}属性被获取了`);
                return target[key]
            },
            set(target, key, newValue) {
                console.log(target,`对象的${key}属性对应的键值被改为了${newValue}`);
                target[key] = newValue
                return newValue;
            }
        })

        console.log(proxyObj.name);
        console.log(proxyObj.age);
        proxyObj.age = 20
    script>

Proxy-Reflect_第2张图片

Reflect(是一个对象)

Reflect(反射):用于替代Object本身不应有的方法
Proxy-Reflect_第3张图片

Reflect的常用方法

Proxy-Reflect_第4张图片

使用reflect重构proxy的写法

 <script>
        const obj = {
            name:'Li',
            age:18,
            gender:'man'
        }
       
        const proxyObj = new Proxy(obj, {
            get(target, key) {
                console.log(target,`对象的${key}属性被获取了`);
                return Reflect.get(target, key)
            },
            set(target, key, newValue) {
                console.log(target,`对象的${key}属性对应的键值被改为了${newValue}`);
                Reflect.set(target, key, newValue)
                return newValue;
            }
        })

        console.log(proxyObj.name);
        console.log(proxyObj.age);
        
    script>

Reflect成功set值时会返回一个布尔值

设置,获取的写法

<script>
        const obj = {
            _name:'Li',
            get name() {
                return this._name
            },
            set name(value) {
                this._name = value
            }
        }
       
        obj.name = 'LiLi'
        console.log(obj.name);
        
    script>

receiver参数

receiver就是代理对象
Reflect在传递receiver后,obj中的this就变成了receiver(也就是代理对象proxyObj)

<script>
        const obj = {
            _name:'Li',
            get name() {
                return this._name
            },
            set name(value) {
                this._name = value
            }
        }
        
        const proxyObj = new Proxy(obj, {
            get(target, key, receiver) {
                console.log('get----', key, receiver);
                let res = Reflect.get(target, key, receiver);
                return res;
            },
            set(target, key, newValue, receiver) {
                console.log('set----', key, receiver);
                return Reflect.set(target, key, newValue, receiver)
            }
        })
        proxyObj.name = 'LiLi'
        console.log(proxyObj.name);
        
    script>

Reflect中construct的作用

 <script>
        //执行Student中的函数,但是创建出来的却是Teacher类型
        function Student(name, age) {
            this.name = name;
            this.age = age
        }
        function Teacher(name, age, gender) {
            this.name = name
            this.age = age
            this.gender = gender
        }
        
        const obj = Reflect.construct(Student, ['Li', 20], Teacher)
        console.log(obj);
    script>

你可能感兴趣的:(深入JavaScript高级,javascript,前端)