当前位置: 首页 > news >正文

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>

在这里插入图片描述
确实可以通过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>

在这里插入图片描述

Reflect(是一个对象)

Reflect(反射):用于替代Object本身不应有的方法
在这里插入图片描述

Reflect的常用方法

在这里插入图片描述

使用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>

相关文章:

  • 容器-基础
  • GC垃圾回收
  • 3D场景的制作步骤
  • 【精讲】后台项目 采用vue2框架 完整版内含详细注释 2
  • mac vscode debug安装调试moodle
  • PyTorch(一)安装与环境配置
  • 全网最牛自动化测试框架系列之pytest(7)-yield与终结函数
  • JSR303校验(1)
  • Nacos - 支持PostgreSQL
  • CFD网格质量评估标准
  • 网课答案公众号题库系统
  • 详解AVL树(二叉搜索平衡树)【C++实现】
  • 网课答案公众号搭建方法
  • 牛客网练习题(函数部分)
  • 仿everything的文件搜索工具项目详解:Part3
  • Django 博客开发教程 8 - 博客文章详情页
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java|序列化异常StreamCorruptedException的解决方法
  • javascript 总结(常用工具类的封装)
  • JS函数式编程 数组部分风格 ES6版
  • orm2 中文文档 3.1 模型属性
  • python3 使用 asyncio 代替线程
  • Redis 中的布隆过滤器
  • spring学习第二天
  • 从零开始在ubuntu上搭建node开发环境
  • 分布式熔断降级平台aegis
  • 简单数学运算程序(不定期更新)
  • 06-01 点餐小程序前台界面搭建
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • (笔试题)分解质因式
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (学习日记)2024.01.09
  • (一)UDP基本编程步骤
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转)菜鸟学数据库(三)——存储过程
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .gitignore文件_Git:.gitignore
  • .NET 常见的偏门问题
  • .netcore 获取appsettings
  • @ConfigurationProperties注解对数据的自动封装
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [.net]官方水晶报表的使用以演示下载
  • [145] 二叉树的后序遍历 js
  • [20190113]四校联考
  • [22]. 括号生成
  • [APUE]进程关系(下)
  • [c]统计数字
  • [docker]docker网络-直接路由模式
  • [FTP]pureftp部署和优化
  • [HNOI2015]实验比较
  • [java刷算法]牛客—剑指offer链表有环的入口、反转链表、合并排序链表
  • [Latex] \bibitem{} | .bbl 格式参考文献转换与获得
  • [LeetCode] Contains Duplicate