js语法---理解反射Reflect对象和代理Proxy对象

Reflect

基本要点

        反射:reflect是一个内置的全局对象,它的作用就是提供了一些对象实例的拦截方法,它的用法和Math对象相似,都只有静态方法和属性,同时reflect也没有构造器,无法通过new运算符构建实例对象(无实例的全局对象);也就是说reflect相当于一个工具类,只对外提供方法进行使用。

tips 拦截方法:拦截方法是指,通过自身方法去覆盖掉原有的默认方法,这样就只会生效拦截方法的操作,而不执行默认操作(例如,setter的作用,覆盖了原有的赋值操作),

这里使用了reflect的方法就不需要再使用默认的方法了

运用示例

以下使用几个简单的reflect的对比示例

Reflect.ownKeys()

获取对象的所有属性(不限于字符串),返回一个数组 ,作用类似Object.keys

Reflect.ownKeys(target)target:获取自身属性键的目标对象。
let obj ={content: 'hello world',length: 11,char: 'utf-8'
}let Keys = Object.keys(obj) // 返回一个由属性名组成的数组
console.log(Keys); // ['content', 'length', 'char']let keys = Reflect.ownKeys(obj) // 返回一个由属性名组成的数组
console.log(keys); // ['content', 'length', 'char']

         这两个方法的效果一致都能拿到对象所有的属性名,但是Object.keys只能得到对象属性的字符串值,如果一个对象的属性包含symbol类型,就无法将其正确的识别出来,而Reflect.ownKeys就可以做到。

关于symbol类型可以参考:js基本类型---symbol标识符_js symbol属于什么类型-CSDN博客

 

Reflect.has()

判定对象中是否存在某个属性,与 in 操作符 相同,返回Boolean值。

let isChar = Reflect.has(obj, 'char') // 判断属性是否存在
console.log(isChar); // true

 Reflect.get()

返回对象(数组)中指定属性的值

Reflect.get(target, propertyKey[, receiver])// target 需要取值的目标对象// propertyKey 需要获取的值的键值// receiver 如果target对象中指定了getter,receiver则为getter调用时的this值。
let content = Reflect.get(obj, 'content') // 获取属性值
console.log(content); // hello world

 

Reflect.set()

静态方法 Reflect.set() 在一个对象上设置一个属性的值,返回Boolean值

Reflect.set(target, propertyKey, value)
Reflect.set(target, propertyKey, value, receiver)//target 设置属性的目标对象。//propertyKey 设置的属性的名称。//value 设置的值。// receiver 如果遇到 setter,receiver则为setter调用时的this值。
// obj.content = '你好,世界' // 设置属性值let setContent = Reflect.set(obj, 'content', '你好,世界') // 设置属性值
console.log(setContent); // true,成功时返回true,否则返回false
console.log(Reflect.get(obj, 'content') ); // 你好,世界
console.log(obj.content); // 你好,世界

 

Reflect.deleteProperty()

静态方法 Reflect.deleteProperty() 允许用于删除属性。它很像delete obj.key,但它是一个函数,成功时返回true,否则返回false,这里的成功是根据结果来看的,如果属性不存在,则返回true,否则返回false

Reflect.deleteProperty(target, propertyKey)// target 删除属性的目标对象。// propertyKey 需要删除的属性的名称。

 

delete obj.content // 删除属性
console.log(obj); // {length: 11, char: 'utf-8'}let deleteContent = Reflect.deleteProperty(obj, 'content') // 删除属性
console.log(deleteContent); // true,成功时返回true,否则返回false,这里的成功是根据结果来看的,如果属性存在,则返回true,否则返回false
console.log(obj); // {length: 11, char: 'utf-8'}
console.log(obj);

为什么使用reflect

Reflect 提供的是一整套反射能力 API,它的调用方式,参数和返回值都是统一风格的,在Reflect 出现之前我们只是利用分散的 API 完成一些动态编程的事情,让动态编程有了一个统一的使用标准

和proxy的关系

proxy是代理对象,它的构造器中就包含了和Reflect相同的方法,当使用proxy代理一个引用类型时,就可以简洁的使用Reflect来实现动态编程的效果,

Reflect和proxy的切合度很高,同时也能够避免使用过多分散API带来的隐性错误(如receiver可以解决this的指向问题)和代码的冗余

总之,reflect整合了一套API用于动态化编程,它可以方便简洁的实现proxy的动态拦截代理

tips 动态编程:响应式数据的原理,当修改页面上的某一个值时,页面效果也随之改变

Proxy

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。

构造器

const p = new Proxy(target, handler)// target 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。// handler 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为,比如访问和赋值时的而外操作。

Proxy.revocable()

Proxy.revocable() 方法可以用来创建一个可撤销的代理对象。返回一个包含了代理对象本身和它的撤销方法的可撤销 Proxy 对象。

Proxy.revocable(target, handler);
// target 将用 Proxy 封装的目标对象。可以是任何类型的对象,包括原生数组,函数,甚至可以是另外一个代理对象。// handler 一个对象,其属性是一批可选的函数,这些函数定义了对应的操作被执行时代理的行为。

代理的意义

        首先代理的对象和原对象的属性和值是绑定一致的,可以理解为指向同一个内存地址,也就是说对代理对象的所有操作结果,最终都会回到原对象中,这个过程就可以实现一些其他操作,例如,改变一个对象的值时,将页面重载一遍,引起页面的变化,这个过程就是响应

一个proxy示例


let obj = {name: '张三',age: 20,sex: '男',/*** @param {any} val*/set address(val){this.address = val;return val;}
}const p = new Proxy(obj,{get: (obj,key,receiver)=>{let res = Reflect.get(obj,key,receiver);return res;},set: (obj,key,val,receiver)=>{if(typeof val == 'number'){console.log('不能设置数字')return;}let res = Reflect.set(obj,key,val,receiver);return res;}
})
p.name='李四';
p.age=18;
console.log(obj,p)

可以看到 被代理的对象obj会受到p的影响触发改变,而对代理对象属性赋值时,我们可以在中间穿插其他操作,如这里不允许对属性赋值数字,

完整代码和结果展示

reflect.js

let obj ={content: 'hello world',length: 11,char: 'utf-8'
}let Keys = Object.keys(obj) // 返回一个由属性名组成的数组
console.log(Keys); // ['content', 'length', 'char']let keys = Reflect.ownKeys(obj) // 返回一个由属性名组成的数组
console.log(keys); // ['content', 'length', 'char']let isChar = Reflect.has(obj, 'char') // 判断属性是否存在
console.log(isChar); // truelet content = Reflect.get(obj, 'content') // 获取属性值
console.log(content); // hello world
console.log(obj.content); // hello world// obj.content = '你好,世界' // 设置属性值let setContent = Reflect.set(obj, 'content', '你好,世界') // 设置属性值
console.log(setContent); // true,成功时返回true,否则返回false
console.log(Reflect.get(obj, 'content') ); // 你好,世界
console.log(obj.content); // 你好,世界delete obj.content // 删除属性
console.log(obj); // {length: 11, char: 'utf-8'}let deleteContent = Reflect.deleteProperty(obj, 'content') // 删除属性
console.log(deleteContent); // true,成功时返回true,否则返回false,这里的成功是根据结果来看的,如果属性存在,则返回true,否则返回false
console.log(obj); // {length: 11, char: 'utf-8'}
console.log(obj);

proxy.js 


let obj = {name: '张三',age: 20,sex: '男',/*** @param {any} val*/set address(val){this.address = val;return val;}
}const p = new Proxy(obj,{get: (obj,key,receiver)=>{let res = Reflect.get(obj,key,receiver);return res;},set: (obj,key,val,receiver)=>{if(typeof val == 'number'){console.log('不能设置数字')return;}let res = Reflect.set(obj,key,val,receiver);return res;}
})
p.name='李四';
p.age=18;
console.log(obj,p)

更多内容

更多Reflect和proxy相关的方法和属性可以查看:

Reflect - JavaScript | MDN (mozilla.org)

Proxy() 构造函数 - JavaScript | MDN (mozilla.org)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xcode和iPhone真机或者watch真机连接问题

1.如果真机是第一次连接xocde,就需要开启真机上的开发者模式,开启开发者模式的方式: iphone/ipad开启方式: 设置 > 隐私与安全 > 开发者模式 > 开启,然后重启就可以了 watch设置:很麻烦,看文章…

现代谱估计分析信号的功率谱(1)---AR 模型谱估计

本篇文章是博主在通信等领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对通信等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在通信领域笔记:…

进阶篇06——锁

概述 全局锁 表级锁 表锁 元数据锁 元数据锁是系统自动加的,不需要我们手动执行命令添加。 意向锁 意向锁和元数据锁一样,也是在加行锁的时候自动给表加上相应的意向锁,不需要我们手动添加。 行级锁 行锁 读锁和读锁兼容,写锁…

易舟云财务软件:开启云记账新时代

在数字化浪潮的推动下,财务管理正经历着深刻的变革。易舟云财务软件,作为一款引领时代的云记账平台,以其卓越的功能和便捷的操作,为企业带来了全新的财务管理体验。 云记账,财务管理的未来趋势 云记账,即基…

免费试用【汇通动态域名】体验test.htdns.cn

汇通动态域名下载地址: http://www.htsoft.com.cn/htsoft/htdnssoft.html 下载后汇通动态域名是绿色软件,不用安装,直接运行htdns.exe 点注册 二级域名地方改成您自己要的域名,我输入的是test,点保存,提示让您输入密…

2024年618成交额达7428亿 淘宝京东618交易额数据对比排名

2024年618年中大促已经基本落下帷幕,作为上半年最重要的电商节日,今年的618交易额有多少?今年的交易数据有哪些变化?我们来一起看一下! 根据星图监测数据显示,2024年618期间(天猫5月20日20: 00-…

海外盲盒APP开发,盲盒出海热!

当下,盲盒作为一种热门的娱乐休闲模式,在全球消费市场中都非常火热,各种热门盲盒商品刚一上线就受到了秒杀,受到了各地年轻消费者的追捧! 盲盒全球化对于我国盲盒企业来说是一个新的机会,有助于我国盲盒快…

华为云下Ubuntu20.04中Docker的部署

我想用Docker拉取splash,Docker目前已经无法使用(镜像都在国外)。这导致了 docker pull 命令的失败,原因是timeout。所以我们有必要将docker的源设置在国内,直接用国内的镜像。 1.在华为云下的Ubuntu20.04因为源的原因…

Python 基础:文件

目录 一、从文件中读取数据1.1 读取整个文件1.2 逐行读取 二、写入文件2.1 写入空文件2.2 写入多行2.3 附加到文件 遇到看不明白的地方,欢迎在评论中留言呐,一起讨论,一起进步! 本文参考:《Python编程:从入…

【CT】LeetCode手撕—141. 环形链表

目录 题目1- 思路2- 实现⭐141. 环形链表——题解思路 3- ACM实现 题目 原题连接:141. 环形链表 1- 思路 模式识别 模式1:判断链表的环 ——> 快慢指针 思路 快指针 ——> 走两步慢指针 ——> 走一步判断环:若快慢相遇则有环&a…

大模型推理优化技术概述

大模型推理优化技术概述 KVcache一句话总结:KV cache背景KV cache 计算过程PageAttention概述背景: MHD、MQA、GQA注意力机制MHAMQAGQA Flash Attention KVcache一句话总结: KV cache其实就是通过空间换取时间的方式,通过缓存Atte…

QTday5 2024-06-19

作业要求&#xff1a; 1.思维导图 2.整理代码&#xff1a;TCP服务器 作业1&#xff1a;思维导图 作业2&#xff1a;整理代码 运行代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QList>…

边学边赛拿冠军!北邮学子勇夺昇腾AI原生创新算子挑战赛金奖

导读 如何从零开始学习算子开发&#xff1f;昇腾AI原生创新算子挑战赛冠军“法宝”大揭秘。 “0xCCCCCCCC团队夺冠&#xff01;” 2024年5月9日&#xff0c;在首届昇腾AI原生创新算子挑战赛S1赛季决赛现场&#xff0c;来自北京邮电大学0xCCCCCCCC团队的孙明志和梁昊骞以总分第…

金蝶BI方案与奥威BI:智能、高效的数据分析组合

在当今数据驱动的时代&#xff0c;企业对于快速、准确、全面的数据分析需求日益增长。金蝶BI方案和奥威BI SaaS平台正是为满足这一需求而精心打造的智能数据分析工具。 方案见效快 金蝶BI方案以其高效的数据处理能力&#xff0c;能够快速地将海量数据转化为有价值的信息。通过…

uniapp 微信小程序自定义分享图片

场景&#xff1a;微信小程序用户&#xff0c;点击小程序里商品的分享按钮时&#xff0c;想要不同的商品展示不用的分享内容&#xff0c;比如分享图片上展示商品的图片、价格等信息。分享的UI图如下&#xff1a; 实现方法&#xff1a; 1. 分享按钮&#xff1a;<button open-…

计算机顶级会议和顶级期刊

顶级会议 国际计算机设计会议&#xff08;ICCD&#xff09;&#xff1a;由国际电气与电子工程师协会&#xff08;IEEE&#xff09;主办&#xff0c;是计算机体系结构领域的国际顶级会议之一&#xff0c;已经成功举办四十余届。 NeurIPS&#xff1a;全称神经信息处理系统大会&a…

电感(线圈)具有哪些基本特性

首先&#xff0c;电感&#xff08;线圈&#xff09;具有以下基本特性&#xff0c;称之为“电感的感性电抗” ?①直流基本上直接流过。 ?②对于交流&#xff0c;起到类似电阻的作用。 ?③频率越高越难通过。 下面是表示电感的频率和阻抗特性的示意图。 在理想电感器中&#…

centos7安装FTP服务器

目录 实验背景 一、配置yum源 1、本地yum 2、阿里云yum 二、安装vsftpd 1、安装vsftp服务 2、启动服务并设置开机自启动 3、开放防火墙和SELinux 三、创建用户和FTP目录 1、创建文件目录并配置权限 2、创建ftp组以及用户 四、修改vsftpd.conf文件 1、备份 vsftpd.c…

C/C++ vector模拟实现

模拟实现&#xff1a; 框架 namespace yx {template<class T>class vector{public:typedef T* iterator;private:iterator _start;iterator _finish;iterator _end_of_storage;}; } 这里我们声明定义不分离 reverse() 新开一个空间&#xff0c;拷贝数据&#xff0c;然…

HTML星空特效

目录 写在前面 完整代码 代码分析 运行效果 系列文章 写在后面 写在前面 100行代码实现HTML星空特效。 完整代码 全部代码如下。 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&g…