【JS】Reflect

对象基本方法

JS语法操作对象时,本质上是调用一个内部封装好的函数,该函数中又会调用对象的基本方法,通过官方文档可以看到基本方法。在过去,这些对象的基本方法是不会对外暴露的。

在这里插入图片描述

如下面这段代码,使用JS语法给对象赋值,这种语法会触发JS内部方法,该方法最终会触发对象基本方法 [[Set]]

let obj = { name: "田本初" }
obj.age = 23

Reflect

Reflect 使开发者可以不使用JS语法的方式操作对象,而是直接调用对象基本方法

通过 mdn文档 可以看到基本方法对应 Reflect 的方法名,如 [[Get]] 对应 get(),[[Set]] 对应 set()。

在这里插入图片描述
这里以 [[Get]] 举例并通过 es文档 详细分析:

const obj = {a: 1,b: 2,get c() {return this.a + this.b}
}
console.log(obj.c); // 3
console.log(Reflect.get(obj, 'c')); // 3

[[Get]] 本身有两个参数,propertyKey为对象key, Receiver则为this指向。
通过JS语法(obj.key)读取对象时Receiver默认就是对象本身,无法修改this指向,但通过 Reflect 可以修改:

在这里插入图片描述

const obj = {a: 1,b: 2,get c() {return this.a + this.b}
}
console.log(obj.c); // 3
console.log(Reflect.get(obj, 'c', { a: 10, b: 20 })); // 30

Reflect 通常与 Proxy 配合使用,Proxy可以看本人另一篇文章:Object.defineProperty与Proxy的对比并通过Vue2、3的实现证明Proxy性能优于Object.defineProperty

下面举例,使用 Proxy 代理对象,此时 this 指向就会出现问题

const obj = {a: 1,b: 2,get c() {return this.a + this.b}
}const p = new Proxy(obj, {get(target, key) {console.log('get', key);return target[key];}
})p.c

在访问c时,虽然使用了a和b,但this仍指向原对象obj而非代理对象p,没有触发对a和b的监听,所以控制台只打印了c。使用 Reflect 手动更正 this 指向即可:

const obj = {a: 1,b: 2,get c() {return this.a + this.b}
}const p = new Proxy(obj, {get(target, key, receiver) {console.log('get', key);return Reflect.get(target, key, receiver);}
})p.c

在这里插入图片描述

再比如使用 Object.keys 获取对象键名集合时,默认会忽略类型为Symbol和不可枚举的属性。

在这里插入图片描述
查看 es文档 中Object.keys的实现

在这里插入图片描述
继续查看EnumerableOwnProperties,可以发现默认只取类型为string且可枚举的键

在这里插入图片描述

如果不想采用默认的 Object.keys 实现,可以通过 Reflect 直接使用对象的基本方法 [[OwnPropertyKeys]]

在这里插入图片描述

常用方法

  1. Reflect.apply(target, thisArgument, argumentsList)

    • 作用:调用一个目标函数,并指定 this 和参数。

    • 示例:

      function sum(a, b) {return a + b;
      }
      console.log(Reflect.apply(sum, null, [1, 2])); // 输出 3
      
  2. Reflect.construct(target, argumentsList[, newTarget])

    • 作用:等同于 new target(...argumentsList),但更具灵活性。

    • 示例:

      class MyClass {constructor(name) {this.name = name;}
      }
      const obj = Reflect.construct(MyClass, ['John']);
      console.log(obj.name); // 输出 'John'
      
  3. Reflect.defineProperty(target, propertyKey, attributes)

    • 作用:为对象定义属性,类似于 Object.defineProperty

    • 示例:

      const obj = {};
      Reflect.defineProperty(obj, 'name', {value: 'John',writable: true,configurable: true,enumerable: true
      });
      console.log(obj.name); // 输出 'John'
      
  4. Reflect.deleteProperty(target, propertyKey)

    • 作用:删除对象的属性,类似于 delete obj[propertyKey]

    • 示例:

      const obj = { name: 'John' };
      Reflect.deleteProperty(obj, 'name');
      console.log(obj.name); // 输出 undefined
      
  5. Reflect.get(target, propertyKey[, receiver])

    • 作用:获取对象的属性值,类似于 target[propertyKey]

    • 示例:

      const obj = { name: 'John' };
      console.log(Reflect.get(obj, 'name')); // 输出 'John'
      
  6. Reflect.set(target, propertyKey, value[, receiver])

    • 作用:设置对象的属性值,类似于 target[propertyKey] = value

    • 示例:

      const obj = {};
      Reflect.set(obj, 'name', 'John');
      console.log(obj.name); // 输出 'John'
      
  7. Reflect.has(target, propertyKey)

    • 作用:检查对象是否具有某个属性,类似于 propertyKey in target

    • 示例:

      const obj = { name: 'John' };
      console.log(Reflect.has(obj, 'name')); // 输出 true
      
  8. Reflect.ownKeys(target)

    • 作用:返回一个包含所有自身属性(包括不可枚举属性但不包括 Symbol 属性)的数组,类似于 Object.getOwnPropertyNamesObject.getOwnPropertySymbols 的组合。

    • 示例:

      const obj = { name: 'John', age: 30 };
      console.log(Reflect.ownKeys(obj)); // 输出 ['name', 'age']
      

与Proxy对比

Proxy可以看本人另一篇文章:Object.defineProperty与Proxy的对比并通过Vue2、3的实现证明Proxy性能优于Object.defineProperty

Reflect
只能调用对象的基本操作,比如属性的读取、设置、删除等。Reflect 不会对对象的行为做任何自定义或修改。它的作用只是将 JS 中的内置的对象基本操作标准化为方法,例如,Reflect.get() 只是返回对象的某个属性的值,不会更改对象的行为。

Proxy
用于 拦截和修改 对象。可以自定义对象的行为,甚至修改对象的默认操作(如属性读取、赋值等)。例如,使用 Proxy 的 get 捕捉器可以改变对象属性的获取方式,使得在读取属性时执行一些额外逻辑或返回自定义的值。

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

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

相关文章

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-20 1. Multimodal Fusion with LLMs for Engagement Prediction in Natural Conversation Authors: Cheng Charles Ma, Kevin Hyekang Joo, Alexandria K. Vail, Sunreeta Bhattacharya, Alvaro Fern’andez Ga…

网络层协议——IP

目录 IP层 IP报文格式 IP的理解 运营商 分片与组装 IP层 传输层的TCP或者UDP协议能直接将数据发送到网络中吗?显然不能,封装完的TCP报文还是需要向下交付,经过协议栈,从链路层发送到物理层也就是网路中。 那么tcp做了什么工…

9.创新与未来:ChatGPT的新功能和趋势【9/10】

创新与未来:ChatGPT的新功能和趋势 引言 在探讨人工智能的发展历程时,我们可以看到它已经从早期的图灵机和人工神经网络模型,发展到了今天能够模拟人类智能的复杂系统。人工智能的起源可以追溯到20世纪40年代,而它的重要里程碑包…

【ARM】MDK-当选择AC5时每次点击build都会全编译

1、 文档目标 解决MDK中选择AC5时每次点击build都会全编译 2、 问题场景 在MDK中点击build时,正常会只进行增量编译,但目前每次点击的时候都会全编译。 3、软硬件环境 1 软件版本:Keil MDK 5.38a 2 电脑环境:Window 10 4、解决…

centos7 配置 docker 国内镜像源

1.修改配置文件/etc/docker/daemon.json sudo vim /etc/docker/daemon.json2.增加或修改以下配置内容 {"registry-mirrors": ["https://dockerproxy.com","https://hub-mirror.c.163.com","https://mirror.baidubce.com","http…

网页爬虫法律与道德:探索法律边界与道德规范

目录 引言 一、网络爬虫技术概述 1.1 定义与功能 1.2 技术原理 1.3 案例分析 二、网络爬虫的法律边界 2.1 合法性要求 2.2 刑事风险 2.3 案例分析 三、网络爬虫的道德规范 3.1 尊重版权和隐私 3.2 合理使用爬虫技术 3.3 透明度和社会责任 四、技术挑战与应对策略…

面试经典 150 题:力扣88. 合并两个有序数组

每周一道算法题启动 题目 【题目链接】 【解法一】合并后排序 排序后的数组自动省略0的数字&#xff0c;又学到了 class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {//合并两个数组后排序for(int i0; i<…

傅里叶变换及其应用笔记

傅里叶变换 预备知识学习路线扼要描述两者之间的共同点&#xff1a;线性运算周期性现象对称性与周期性的关系周期性 预备知识 学习路线 从傅里叶级数&#xff0c;过度到傅里叶变换 扼要描述 傅里叶级数&#xff08;Fourier series&#xff09;&#xff0c;几乎等同于周期性…

面经 | ES6

ES6 ES6Promise对象创建Promise三个状态resolve/reject 和微任务的关系await set vs weakSetmap vs weakMap ES6 Promise对象 new Promise(excutor);excutor是一个函数,会立刻执行;then里的回调函数&#xff0c;会进入微任务队列&#xff1b;then会返回一个新的promise对象aw…

LeetCode 面试经典150题 137.只出现一次的数字II

题目&#xff1a; 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 思路&#xff1a; 方法一&#xf…

Java | Leetcode Java题解之第435题无重叠区间

题目&#xff1a; 题解&#xff1a; class Solution {public int eraseOverlapIntervals(int[][] intervals) {if (intervals.length 0) {return 0;}Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] interval1, int[] interval2) {return i…

如何把python(.py或.ipynb)文件打包成可运行的.exe文件?

将 Python 程序打包成可执行的 .exe 文件&#xff0c;通常使用工具如 PyInstaller。这是一个常用的 Python 打包工具&#xff0c;可以将 Python 程序打包成独立的可执行文件&#xff0c;即使没有安装 Python 也能运行。 步骤&#xff1a; 1. 安装 PyInstaller 使用 conda 安…

风力发电机叶片表面缺陷识别检测数据集yolo数据集 共7000张

风力发电机叶片表面缺陷识别检测数据集yolo数据集 共7000张 风力发电机叶片表面缺陷识别数据集&#xff08;Wind Turbine Blade Defects Recognition Dataset, WTBDRD&#xff09; 摘要 WTBDRD 是一个专门为风力发电机叶片表面缺陷识别而设计的数据集&#xff0c;旨在为相关领…

HttpServletRequest简介

HttpServletRequest是什么&#xff1f; HttpServletRequest是一个接口&#xff0c;其父接口是ServletRequest&#xff1b;HttpServletRequest是Tomcat将请求报文转换封装而来的对象&#xff0c;在Tomcat调用service方法时传入&#xff1b;HttpServletRequest代表客户端发来的请…

HTML5好看的水果蔬菜在线商城网站源码系列模板2

文章目录 1.设计来源1.1 主界面1.2 商品列表界面1.3 商品详情界面1.4 其他界面效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/142059220 HTML5好看的水果蔬菜在线商城…

FortiGate OSPF动态路由协议配置

1.目的 本文档针对 FortiGate 的 OSPF 动态路由协议说明。OSPF 路由协议是一种 典型的链路状态(Link-state)的路由协议,一般用于同一个路由域内。在这里,路由 域是指一个自治系统,即 AS,它是指一组通过统一的路由政策或路由协议互相交 换路由信息的网络。在这个 AS 中,所有的 …

OTTO奥托机器人开发总结

OTTO机器人是一个开源外壳&#xff0c;硬件和软件的桌面机器人项目&#xff0c;非常适合新手研究和拓展。 我一直希望找一个合适的项目入手研究机器人&#xff0c;这种项目最好是软硬件都开源的&#xff0c;可以随着自己的想法无限的扩展和私人订制&#xff0c;做为初学者&…

Vue3:element-plus el-Table列表合计处理显示字符串类型/计算合计数值

需求整理 1.使用element组件库中的 el-table组件实现图上 底部当前页合计的功能。在一般的情况下&#xff0c;只需要计算数值部分的值&#xff0c;因为组件中的方法中处理的就是将值的类型转换成数值类型&#xff0c;像string类型的字符串的话&#xff0c;在进行转换的时候会出…

计算机毕业设计电影票购买网站 在线选票选座 场次订票统计 新闻留言搜索/springboot/javaWEB/J2EE/MYSQL数据库/vue前后分离小程序

系统功能 ‌在线选票选座‌&#xff1a;用户可浏览电影场次&#xff0c;选择座位并生成订单。‌场次订票统计‌&#xff1a;系统实时统计各场次订票情况&#xff0c;便于影院管理。‌新闻发布与留言‌&#xff1a;发布最新电影资讯&#xff0c;用户可留言互动。‌搜索功能‌&a…

springboot整合nacos

docker安装nacos参考docker安装各个组件的命令 一、目录结构 二、引入必要依赖 <!-- nacos服务注册与发现 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>…