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

js版本之ES6特性简述【Proxy、Reflect、Iterator、Generator】(五)

目录

Proxy

Reflect

静态方法

部分实例

Iterator

实际开发迭代器的使用实例

迭代器(Iterator)应用

Generator

Proxy

Proxy 是 ES6 中新增的对象

  • Proxy 是JavaScript中的内置对象,它提供了一种机制,可以拦截并自定义各种操作,如属性访问、函数调用、构造函数调用等。
  • Proxy 构造函数接受两个参数目标对象(被代理的对象)和一个处理器对象(用于定义拦截器)。
// 写法:target是目标对象,handler是处理器对象
const proxy = new Proxy(target, handler);

 详解请看:ES6之---Proxy简介

Reflect

Proxy 是 ES6 中新增的对象【:不可使用new操作符生成实例】

特点:

  • 将 Object 对象的一些明显属于语言内部的方法(如 Object.defineProperty)放到 Reflect 对象上,现阶段,某些方法同时在 Object 和 Reflect 对象上部署,未来新的方法只在 Reflect 对象上部署。也就是说,从 Reflect 对象上可以获得语言内部的方法。
  • 修改某些Object的内部方法返回结果,使其变的合理。(以Object.defineProperty为例, 现在如果没有办法定义时,则会报错,放在Reflect上面,则会返回false)
  • 让 Object 操作都编程函数行为,某些 Object 操作是命令式,比如 name in obj 和 delete obj [name],而 Reflect.has(obj, name) 和 Reflect.deleteProperty(obj, name) 让它们变成了函数行为。
  • Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法,这就是 Proxy 对象可以方便的调用对应的 Reflect 方法来完成默认行为,作为修改行为的基础。也就是说,无论 Proxy 怎么修改默认行为,我们总可以在 Reflect 上获取到默认行为。

静态方法

  • Reflect.apply
  • Reflect.construct
  • Reflect.defineProperty
  • Reflect.deleteProperty
  • Reflect.get
  • Reflect.getOwnPropertyDescriptor
  • Reflect.getPrototypeOf
  • Reflect.has
  • Reflect.isExtensible
  • Reflect.ownKeys
  • Reflect.preventExtensions
  • Reflect.set
  • Reflect.setPrototypeOf

部分实例

Reflect.construct(target, args)

  • Reflect.construct 方法等同于 new target(…args),这提供了一种不使用 new ,来调用构造函数的方法。
  • 如果 Reflect.construct () 方法的第一个参数不是对象,会报错。
// 说明1的例子如下: 
function Greeting(name) {this.name = name;
}
// new 的写法
const instance = new Greeting('张三');
// Reflect.construct 的写法
const instance1 = Reflect.construct(Greeting, ['张三']); // {name: '张三'}
// 说明2的例子如下: 
console.log(Reflect.construct(1, 'baz'))  // TypeError: Reflect.construct called on non-object

Reflect.deleteProperty(target, name)

  • Reflect.deleteProperty方法等同于delete obj[name],用于删除对象的属性。
  • 注意:**如果删除成功,或者被删除的属性不存在,返回 true ;删除失败,被删除的属性依然存在,返回 false **
  • 如果 Reflect.deleteProperty() 方法的第一个参数不是对象,会报错。
// 说明1,2的例子如下: 
var myObject = {foo: 1,
}
console.log(Reflect.deleteProperty(myObject, 'foo')) // true
console.log(Reflect.deleteProperty(myObject, 'zzz')) // true
// 此时的myObject 就是{}

Reflect.get(target, name, receiver)

  • Reflect.get方法查找并返回 target 对象的 name 属性值,如果没有该属性,则返回 undefined 。
  • 如果 name 属性部署了读取函数(getter),则读取函数的 this 绑定 receiver 。
  • 如果第一个参数不是对象, Reflect.get 方法会报错。
// 说明1的例子如下: 
var myObject = {foo: 1,bar: 2,get baz() {return this.foo + this.bar;},
}
console.log(Reflect.get(myObject, 'foo')) // 1 
console.log(Reflect.get(myObject, 'bar')) // 2
console.log(Reflect.get(myObject, 'baz')) // 3 没有传receiver,则this取原对象
console.log(Reflect.get(myObject, 'zzz')) // undefined
// 说明2的例子如下: 
const otherObject = {foo: 3,bar: 4
}
console.log(Reflect.get(myObject, 'baz', otherObject)) // 7
// 说明3的例子如下: 
console.log(Reflect.get(1, 'baz'))  // TypeError: Reflect.get called on non-object

Reflect.has(target, name) 

  • Reflect.has方法对应name in obj里面的in运算符。
  • 如果 Reflect.has() 方法的第一个参数不是对象,会报错。
// 说明1的例子如下: 
var myObject = {foo: 1,
}
console.log(Reflect.has(myObject, 'foo')) // true
console.log(Reflect.has(myObject, 'zzz')) // false
// 说明2的例子如下: 
console.log(Reflect.has(1, 'baz'))  // TypeError: Reflect.has called on non-object

观察者模式实例

// 这里就是简单观察者的核心逻辑,主要实现两个功能,一个就是observe,另一个就是observable
// 先定义了一个Set 集合,所有观察者函数都放进这个集合。
// observable 函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数
// 拦截函数 set 之中,会自动执行所有观察者
const queuedObservers = new Set();
const observe = fn => queuedObservers.add(fn);
const observable = obj => new Proxy(obj, {set});
function set(target, key, value, receiver) {const result = Reflect.set(target, key, value, receiver);queuedObservers.forEach(observer => observer());return result;
}
// 使用如下:
const person = observable({name: '张三',age: 20
});
function print() {console.log( ${person.name}, ${person.age} )
}
observe(print);
person.name = '李四';

Iterator

Iterator即迭代器,它是一种接口,为各种不同的数据结构提供了统一的访问机制,换句话说,只要有任何数据结构部署了迭代接口,就可以使用统一的方式的来遍历它。

ES6为数组和普通对象,以及新增的Map和Set提供了统一的遍历机制:迭代器(Iterator),并新增了for … of语法来使用迭代器。

实现可迭代接口的数据结构,一般都自身实现或继承了以Symbol.iterator属性的,就属于可迭代对象。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。

一个包含next()方法的对象,才可以称为一个迭代对象。next()对象的会有返回一个对象,对象中包含两个值,如下所示:

  • value:迭代器返回的任何JavaScript值。donetrue时可省略。
  • done:一个布尔值,为false时表示迭代未停止,为true时立即停止迭代器,且可以省略value的值。

实际开发迭代器的使用实例

实际开发中,为每一个对象单独定义一个迭代器属性实在不是一件聪明事。我们可以仿照js引擎部署迭代器的做法,将迭代器署在对象原型上,这样由某个构造函数或类(指es6的class)所生成的每个对象都可以方便地进行遍历了。 

构造函数写法

function Student(name, age){this.name = name;this.age = age;
}
Student.prototype[Symbol.iterator] = function(){let index = 0;let keys = [...Object.keys(this)];let _this = this;keys.sort((key1, key2) => { //按字母顺序对属性排序return key1 < key2 ? -1 : 1;})return {next(){return index < keys.length ?{value: _this[keys[index++]], done: false} :{value: undefined, done: true}}}
}let s = new Student('小明', 24);
for(let val of s){console.log(val);
}  //输出:24 '小明'

类写法

class Student{constructor(name, age){this.name = name;this.age = age;}[Symbol.iterator](){let index = 0;let keys = [...Object.keys(this)];keys.sort((key1, key2) => { //按字母顺序对属性排序return key1 < key2 ? -1 : 1;})let _this = this;return {next(){return index < keys.length ?{value: _this[keys[index++]], done: false} :{value: undefined, done: true}}}}
}

迭代器(Iterator)应用

【1】 解构赋值

Array和Set的解构赋值就是借助迭代器来实现的

js引擎依次在左右两侧结构上调用next方法,进行逐个赋值,这样左侧数组的每个变量会对应被赋为右侧的值。

const [a, b] = [1, 2];             //a: 1, b: 2const [c, d] = new Set([3, 4]);    //c: 3, d: 4

【2】扩展运算符

ES6的扩展运算符可以将数组展开为一列,这也是借助Iterator接口实现的

let args = ['name', 'age'];
f(...args);                    //等价于f('name', 'age')

【3】return和throw

迭代器对象除了必要的next方法外,还可以部署return和throw方法,用于在for … of语句中终止遍历和抛出异常。

let s = {name: '小明',age: 24,[Symbol.iterator]: function (){let index = 0;let keys = ['name', 'age'];let _this = this;return {next(){return index < keys.length ?{value: _this[keys[index++]], done: false} :{value: undefined, done: true}},return(){...  //结束循环前可以在这里执行某些操作,如关闭文件系统等return {done: true}},throw(){...  //抛出异常时可以在这里执行某些操作return {done: true}}}}
}for(let val of s){console.log(val);break;   //该语句会触发迭代器对象的return方法
}for(let val of s){console.log(val);throw new Error(); //该语句会触发迭代器对象的throw方法
}

【4】Iterator与Generator函数

Generator函数调用之后返回的就是一个迭代器对象,这个对象原生就具备next接口

let s = {name: '小明',age: 24,[Symbol.iterator]: function* (){yield this.name;yield this.age;}
}

Generator 

Generator【生成器】是ES6中提供的一种异步编程解决方案定义Generator函数在function关键字和函数名中间使用*星号,函数内部使yield关键字定义不同的状态

注:需要注意的是,生成器函数定义时需要在函数关键字 function 后面加上星号(*),以标识该函数为生成器函数。另外,yield 关键字只能在生成器函数内部使用

function* testGenerator(){// yield定义一个状态yield1 'css6之generator'yield 'es新特性'return 'generator'        // 终结Generator,后面即使有yield关键字也无效
}
const g=testGenerator()       // 返回 Generator 对象,通过next()方法移动状态g.next()                      //{value:'-碗周',done:false }
g.next()                      //{value:'es新特性',done:false }
g.next()                      //{ value:generator',done:true }

Generator详解

此文借鉴了一下博主的优秀文章

https://blog.csdn.net/Rookie_lei/article/details/140790532

https://blog.csdn.net/qq_41694291/article/details/103432571

上一章:js版本之ES6特性简述【let和const、数组、函数、集合、Symbol】(四)

相关文章:

js版本之ES6特性简述【Proxy、Reflect、Iterator、Generator】(五)

目录 Proxy Reflect 静态方法 部分实例 Iterator 实际开发迭代器的使用实例 迭代器&#xff08;Iterator&#xff09;应用 Generator Proxy Proxy 是 ES6 中新增的对象 Proxy 是JavaScript中的内置对象&#xff0c;它提供了一种机制&#xff0c;可以拦截并自定义各种…...

CSS实现一个自定义的滚动条

要使用CSS创建一个自定义的滚动条&#xff0c;你可以使用伪元素和CSS的伪类来控制滚动条的外观和行为。以下是一个简单的例子&#xff0c;展示如何为任何HTML元素添加一个自定义的滚动条样式&#xff1a; <!DOCTYPE html> <html lang"en"> <head> …...

CKA认证 | Day8 K8s安全

第八章 Kubernetes安全 1、Kubernetes RBAC授权 Kubernetes 基于角色的访问控制&#xff08;Role-Based Access Control, RBAC&#xff09; 是一种强大的权限管理机制&#xff0c;用于控制用户、用户组、服务账户对 Kubernetes 集群资源的访问。通过 RBAC&#xff0c;可以细…...

深度分析java 使用 proguard 如何解析混淆后的堆栈

经过proguard混淆过后&#xff0c;发生异常时堆栈也进行了混淆&#xff0c;那么如果获取的原始的堆栈呢&#xff1f;我们下面来看下 使用proguard 根据mapping文件直接解析 import proguard.obfuscate.MappingReader; import proguard.retrace.FrameInfo; import proguard.re…...

bash 中 ${-#*i} 是什么意思?

-------------------------------------------------- author: hjjdebug date: 2024年 12月 25日 星期三 17:43:45 CST description: bash 中 ${-#*i} 是什么意思? -------------------------------------------------- 在centos 的 /etc/profile 中有这样的语句 for i in /…...

什么是Top-p采样与Top-k采样?大模型推理时如何同时设置?解析Transformers库源代码

什么是Top-p采样与Top-k采样&#xff1f;大模型推理时如何同时设置&#xff1f; 在自然语言生成&#xff08;NLG&#xff09;和大规模语言模型推理中&#xff0c;Top-k采样 和 Top-p采样 是两种常用的解码策略&#xff0c;用于控制生成文本的多样性和质量。它们在生成过程中对…...

java队列--数据结构

文章目录 前言本文源代码网址&#xff1a;https://gitee.com/zfranklin/java/tree/master/dataStructure/src/com/njupt/queue队列的性质数组队列成员变量方法 链表栈成员变量方法 总结 前言 顺序表和链表两种存储方式实现数据结构–队列。 本文源代码网址&#xff1a;https:/…...

【WebSocket】tomcat内部处理websocket的过程

websocket请求格式 浏览器请求 GET /webfin/websocket/ HTTP/1.1。 Host: localhost。 Upgrade: websocket。 Connection: Upgrade。 Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg。 Origin: http://服务器地址。 Sec-WebSocket-Version: 13。 服务器响应 HTTP/1.1 101 Swi…...

【踩坑/Linux】Vmware中的Ubuntu虚拟机无法访问互联网

Vmware中的Ubuntu虚拟机无法访问互联网 首先前提是我的系统是Ubuntu 16.04系统&#xff0c;vmware workstation选择的是NAT模式&#xff0c;虚拟机内连不上网络 ping www.baidu.com ping: unknown host www.baidu.com首先检查 DNS 解析服务&#xff1a;在虚拟机中打开命令提示…...

overleaf中的includegraphics设置图片缩放,居中显示

overleaf中的includegraphics设置图片缩放,居中显示 \includegraphics[width=0.5\textwidth]{example.jpg} \centering 在使用 \includegraphics 命令插入图片时,可以通过设置其参数来缩小图片的显示尺寸,以下是几种常见的方法: 设置宽度或高度 按比例缩小宽度:可以使用…...

IPv6的地址类型

IPv6地址总长度为128bit&#xff0c;被分为8组&#xff0c;每组为4个十六进制数&#xff0c;用冒号分隔&#xff1a; 例如&#xff1a;FC00:0123:4567:8901:ABFD:0987:0000:0023 可缩写为&#xff1a;FC00:0123:4567:8901:ABFD:0987::23 IPv6中取消了v4中的广播&#xff0c;新…...

Elasticsearch:analyzer(分析器)

一、概述 可用于将字符串字段转换为单独的术语&#xff1a; 添加到倒排索引中&#xff0c;以便文档可搜索。级查询&#xff08;如 生成搜索词的 match查询&#xff09;使用。 分析器分为内置分析器和自定义的分析器&#xff0c;它们都是由若干个字符过滤器&#xff08;chara…...

【工作感悟】

1、不返工 - 复述任务 避免返工的前提是先把事情弄清楚&#xff0c;怎么弄清楚&#xff0c;要问到每个细节&#xff0c;怎么确保每个细节都问到了&#xff0c;把要做的事情复述一遍&#xff0c;有必要的话再讲述一下自己打算怎么做&#xff1b;及时对齐工作进度可以避免出错 …...

事件(event) SystemVerilog

1.定义 在数字逻辑仿真中&#xff0c;事件&#xff08;event&#xff09; 是一种机制&#xff0c;用于触发模型中的更新或计算。这种机制是仿真器用来追踪信号的变化以及调度进程执行的核心。 2.分类 事件可以分为以下两种类型&#xff1a; 更新事件&#xff08;Update Even…...

【MySQL学习笔记】关于索引

文章目录 【MySQL学习笔记】关于索引1.索引数据结构2.索引存储3.联合索引3.1 联合索引的b树结构3.2 索引覆盖&#xff1f;回表&#xff1f;3.3 联合索引最左匹配原则3.5 索引下推 4.索引失效 【MySQL学习笔记】关于索引 1.索引数据结构 索引是一种能提高查询速度的数据结构。…...

APIs-day3

1.全选反选案例 <head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width,initial-scale1.0"><title>练习</title><style>*{margin: 0;padding: 0;}table{margin: 100px auto;width: …...

7-1求逆序对数目

目录 题目描述 输入样例: 输出样例: 逆序对的含义&#xff1a; 具体思路&#xff1a; 归并排序&#xff1a; 求逆序对&#xff1a; 代码实现&#xff1a; 对于mid-z1举个例子 题目描述 注意&#xff1a;本问题算法的时间复杂度要求为O(nlogn), 否则得分无效 题目来源&#xff…...

C# 中 Webclient和Httpclient

在C#中&#xff0c;WebClient和HttpClient&#xff0c;这两个类都是用于发起HTTP请求的客户端&#xff0c;它们在使用API上传文件或数据时有不同的优缺点和应用场景。在C#中WebClient是一种较早的网络客户端&#xff0c;而HttpClient是后期提供的更现代的、功能更强大的HTTP客户…...

cesium入门学习三

这期主要学习一下鼠标点击事件以及鼠标滚轮事件。 学习目录总结&#xff1a; cesium入门学习一-CSDN博客 cesium入门学习二-CSDN博客 1.鼠标事件 1.1 点击鼠标左键显示经度、纬度、高度 效果&#xff1a; js代码&#xff1a; var viewer new Cesium.Viewer(cesiumConta…...

swagger,showdoc,apifox,Mock 服务,dubbo,ZooKeeper和dubbo的关系

Swagger、ShowDoc 和 Apifox 之间的区别与优势 Swagger、ShowDoc 和 Apifox 都是用于 API 文档管理和测试的工具&#xff0c;但它们各有特色和适用场景。以下是详细的比较&#xff0c;并附上每个工具的具体用法示例。 1. Swagger 特点与优势&#xff1a; 广泛采用: Swagger…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...