ES6 Reflect 详解(三)

ops/2024/10/21 9:59:18/

Reflect 对象与Proxy 对象一样,也是 ES6 为了操作对象而提供的新 API。 Reflect 对象的设计目的有 4 个。

  1. 将 Object 对象的一些明显属于语言内部的方法(比如 Object.defineProperty ),放到 Reflect 对象上。现阶段,某些方法同时在 Object 和 Reflect 对象上部署,未来的新方法将只部署在 Reflect 对象上。也就是说,从 Reflect 对象上可以拿到语言内部的方法。
  2. 修改某些 Object 方法的返回结果,让其变得更合理。比如, Object.defineProperty(obj, name, desc) 在无法定义属性时,会抛出一个错误,而 Reflect.defineProperty(obj, name, desc) 则会返回 false 。
javascript">// 老写法
try {Object.defineProperty(target, property, attributes);// success
} catch (e) {// failure
}
// 新写法
if (Reflect.defineProperty(target, property, attributes)) {// success
} else {// failure
}
  1. 让 Object 操作都变成函数行为。某些 Object 操作是命令式,比如 name in obj 和 delete obj[name] ,而 Reflect.has(obj, name) 和 Reflect.deleteProperty(obj, name) 让它们变成了函数行为。
javascript">// 老写法
'assign' in Object // true
// 新写法
Reflect.has(Object, 'assign') // true
  1. Reflect对象的方法与 Proxy对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。这就让 Proxy 对象可以方便地调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。
javascript">Proxy(target, {set: function(target, name, value, receiver) {var success = Reflect.set(target, name, value, receiver);if (success) {console.log('property ' + name + ' on ' + target + ' set to ' + value);}return success;}
});

Proxy 方法拦截 target 对象的属性赋值行为。它采用 Reflect.set 方法将值赋值给对象的属性,确保完成原有的行为,然后再部署额外的功能。

常用方法:

Reflect.get(target, propertyKey[, receiver]):获取对象的属性。
Reflect.set(target, propertyKey, value[, receiver]):设置对象的属性。
Reflect.has(target, propertyKey):判断属性是否存在于对象上。
Reflect.deleteProperty(target, propertyKey):删除对象的属性。
Reflect.ownKeys(target):返回对象自身的所有属性的数组。
Reflect.getOwnPropertyDescriptor(target, propertyKey):获取对象属性的描述符。
Reflect.defineProperty(target, propertyKey, attributes):定义或修改对象的属性。
Reflect.preventExtensions(target):阻止对象被扩展。
Reflect.isExtensible(target):判断对象是否可扩展。
Reflect.getExtension(target):获取对象的原型。
Reflect.setPrototypeOf(target, prototype):设置对象的原型。

示例1:使用 Reflect.get

javascript">let obj = { name: "Alice", age: 25 };
let propName = "name";console.log(Reflect.get(obj, propName)); // 输出:Alice
console.log(Reflect.get(obj, "gender")); // 输出:undefined

示例2:使用 Reflect.set

javascript">let obj = { name: "Alice" };// 设置属性
console.log(Reflect.set(obj, "age", 30)); // 输出:trueconsole.log(obj); // 输出:{ name: "Alice", age: 30 }

示例3:使用 Reflect.has

javascript">let obj = { name: "Alice" };console.log(Reflect.has(obj, "name")); // 输出:true
console.log(Reflect.has(obj, "age"));  // 输出:false

示例4:使用 Reflect.deleteProperty

javascript">let obj = { name: "Alice", age: 30 };// 删除属性
console.log(Reflect.deleteProperty(obj, "age")); // 输出:trueconsole.log(obj); // 输出:{ name: "Alice" }

示例5:使用 Reflect.ownKeys

javascript">let obj = { name: "Alice", age: 30 };console.log(Reflect.ownKeys(obj)); // 输出:["name", "age"]

示例6:使用 Reflect.preventExtensions

javascript">let obj = { name: "Alice" };// 防止对象被扩展
console.log(Reflect.preventExtensions(obj)); // 输出:true// 尝试添加新属性
console.log(Reflect.set(obj, "age", 30)); // 输出:false

示例7:使用 Reflect.isExtensible

javascript">let obj = { name: "Alice" };console.log(Reflect.isExtensible(obj)); // 输出:true

示例8:使用 Reflect.getPrototypeOf 和 Reflect.setPrototypeOf

javascript">let proto = { sayHello: function() { console.log("Hello!"); }};
let obj = Object.create(proto);console.log(Reflect.getPrototypeOf(obj) === proto); // 输出:true// 设置新原型
let newProto = { sayGoodbye: function() { console.log("Goodbye!"); }};
Reflect.setPrototypeOf(obj, newProto);console.log(obj.sayGoodbye); // 可以访问新原型上的方法
obj.sayGoodbye(); // 输出:Goodbye!

Reflect 对象提供了一种与 Proxy 陷阱相对应的方法集合,使得拦截 JavaScript 操作更加直观和方便。使用 Reflect可以确保操作的一致性和预期的行为,特别是在需要明确捕获失败情况或错误时。


http://www.ppmy.cn/ops/56229.html

相关文章

一款专业的 Windows 恶意程序分析与清理工具

大家好,今天给大家分享一款专业的 Windows 恶意程序分析与清理工具OpenArk,它能够帮助用户发现系统中隐藏的恶意软件。 OpenArk是一款Windows平台上的开源Ark工具. Ark是Anti-Rootkit(对抗恶意程序)的简写, OpenArk目标成为逆向工…

如何在word中敲出可以点击打勾和取消打勾的方框呢?

文章目录 要解决的问题网上出现的几种不可行的方案发现解决措施 要解决的问题 在word中敲出 点击就可以打对勾和取消对钩的方框 网上出现的几种不可行的方案 插入-> 符号,此方法打出的方框是fixed的,不是我想要的可以自己自主打勾和不打勾的方式。 …

ELK的储存、分析功能介绍!

ELK是由Elasticsearch、Logstash和Kibana三个开源软件组成的日志管理解决方案,它们在日志数据的储存和分析方面发挥着重要作用。 储存功能: Elasticsearch:Elasticsearch是一个基于Lucene的搜索服务器,它提供了一个分布式多用户能…

探索金融数据API:现代投资的关键工具

在当今快节奏的金融市场中,实时准确的数据对于投资者而言至关重要。金融数据API(Application Programming Interface)成为了投资者获取和管理数据的核心工具。本文将探讨金融数据API的基本概念、用途及其对投资策略的影响。 什么是金融数据A…

视频技术助力智慧城市一网统管:视频资源整合与智能化管理

随着信息技术的飞速发展,智慧城市已成为现代城市发展的重要方向。在智慧城市建设中,一网统管作为城市管理的重要策略,通过整合各类信息资源,实现资源的优化配置和问题的快速响应。其中,视频技术作为一网统管场景中的关…

【问题记录】Nodeclub运行make install报错npm ERR! code ELIFECYCLE

问题展示 按照官网给出的教程进行到make install这一步卡住了,显示了如下报错。 解决方法 将node.js版本变更为能够识别代码的版本,我将版本修改成了16.14.0以后成功运行。 nvm install 16.14.0

Unity 常用取整方法

向下取整:Mathf.FloorToInt() 向上取整:Math.Ceiling 截断取整:(int) 四舍五入:Mathf.RoundToInt e.NewValues.value.ToString(“F0”) 百分比: int i 400; int j 200; string p ((double)i…

从Docker 网络看IaC

【引子】近来,老码农又一次有机会实施IaC 了, 但是环境有了新的变化,涵盖了云环境、虚拟机、K8S 以及Docker,而网络自动化则是IaC中的重要组成,温故知新,面向Docker 的网络是怎样的呢? Docker …