ES6学习(四)-- Reflect / Promise / Generator 函数 / Class

文章目录

  • 1. Reflect
    • 1.1 代替Object 的某些方法
    • 1.2 修改某些Object 方法返回结果
    • 1.3 命令式变为函数行为
    • 1.4 ! 配合Proxy
  • 2. ! Promise
    • 2.1 回调地狱
    • 2.2 Promise 使用
    • 2.3 Promise 对象的状态
    • 2.4 解决回调地狱的方法
    • 2.5 Promise.all
    • 2.6 Promise.race
  • 3. Generator 函数
    • 3.1 基本语法
    • 3.2 手动版本函数
    • 3.3 自动版本函数
  • 4. Class 语法
    • 4.1 类的写法
    • 4.2 get() / set() 拦截用法
    • 4.3 类的静态属性和方法
  • 5. Class 继承
    • 5.1 基本语法
    • 5.2 利用面向对象思想渲染页面

1. Reflect

Reflect可以用于获取目标对象的行为,它与Object类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与Proxy是对应的。

1.1 代替Object 的某些方法

比如object.defineProperty()

let obj = {}
Reflect.defineProperty(obj,"name",{
value:"kerwin",
writable:false,
enumerable:false
})
console.log(obj)

两者唯一不同的地方是返回Boolean 值。

1.2 修改某些Object 方法返回结果

简单了解就行,面试有时会问。

//老写法
try{
object.defineProperty(target,property,attributes)};
// success
catch (e){
// fail
}
//新写法
if (Reflect.defineProperty(target,property,attributes)){
// success
else{
// fail
}

使用Reflect 的好处:在处理异常错误时不需要try…catch ,只会判断true / false,这样不会打断程序。

1.3 命令式变为函数行为

const obj = {
name:"kerwin"
};
// 老写法
console.log("name"in obj)//true
//新写法
console.log(Reflect.has(obj,'name'))//true
}
// 老写法
delete (obj.name)
// 新写法
Reflect.deleteproperty(obj,"name")

1.4 ! 配合Proxy

之前使用Proxy:

let s = new Set()
let proxy = new Proxy(s,
get(target,key){
//判断如果key 是方法,修正this指向
let value = target[key]
if(value instanceof Function){
//call apply bind
return value.bind(target)}
return value
},
set(){
console.log("set")
})

Reflect 配合 Proxy 使用:

Let s = new Set()
Let proxy = new Proxy(s,
get(target,key){
//判断如果key 是方法,修正this指向
//target[key]
Let value = Reflect.get(target,key)
if (value instanceof Function){
//call apply bind
return value.bind(target)
}
return value
},
set(target,key,value){
Reflect.set(...arguments)
}
})

使用Reflect 可以拿到代理对象的默认行为

Proxy 代理数组非常在行!

let arr = [1,2,3]
Let proxy new Proxy(arr,{
get(target,key){
console.log("get",key)
return-Reflect.get(...arguments)
},
set(){
return Reflect.set(...arguments)
}
})

Reflect 不仅能拦截数组的push() 等方法,而且能拦截无压抑的检测数组长度的改变

2. ! Promise

Promise是异步编程的一种解决方案,比传统的解决方案回调函数更合理和更强大。ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。

  • 指定回调函数方式更灵活易懂。
  • 解决异步回调地狱的问题。

2.1 回调地狱

回调地狱,其实就是回调函数嵌套过多导致的

在这里插入图片描述

·当一个回调函数嵌套一个回调函数的时候
·就会出现一个嵌套结构
·当嵌套的多了就会出现回调地狱的情况

  • 比如我们发送三个ajax请求
  • 第一个正常发送
  • 第二个请求需要第一个请求的结果中的某一个值作为参数
  • 第三个请求需要第二个请求的结果中的某一个值作为参数
ajax("/aaa",function (data)
console.log(data)
ajax("/bbb",function (data)
console.log(data)
ajax("/ccc",function (data)
console.log(data)
}function (
})
}function ()
})
}function ()
)

当代码成为这个结构以后,已经没有维护的可能了。

2.2 Promise 使用

使用Promise 处理异步任务时我们首先先new 一个Promise 构造函数,其中写入一个执行器函数(后面程序按什么情况执行就看执行器函数)
补充:then()方法是异步执行。

意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题。

语法:promise.then(onCompleted, onRejected);

参数

promise必需。Promise 对象。

onCompleted必需。承诺成功完成时要运行的履行处理程序函数。

onRejected可选。承诺被拒绝时要运行的错误处理程序函数。

  1. 第一种使用方法
let pro = new Promise(function(resolve,reject){
//执行器函数
setTimeout(()=>{
reject()
},1000)
})
pro.then(()=>{
console.1og("奖金")
},()=>{
console.1og("没有")
})
  1. 第二种使用方法
pro.then((res)=>{
console.1og("奖金",res)
}).catch((err)=>{
console.1og("没有",err)

2.3 Promise 对象的状态

这一块内容在面试时非常重要!

Promise对象通过自身的状态,来控制异步操作。Promise实例具有三种状态。

  • 异步操作未完成 (pending)
  • 异步操作成功 (fulfilled)
  • 异步操作失败 (rejected)

这三种的状态的变化途径只有两种。

  • 从“未完成”到“成功”
  • 从“未完成”到“失败”

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是Promise这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise实例的状态变化只可能发生一次。
因此,Promise的最终结果只有两种。

  • 异步操作成功,Promise实例传回一个值(value),状态变为fulfilled。
  • 异步操作失败,Promise实例抛出一个错误(error),状态变为rejected。
    在这里插入图片描述

2.4 解决回调地狱的方法

  1. .then.then 链式调用
let pro = new Promise(function(resolve,reject){
//执行器函数
setTimeout(()=>{
reject()
},1000)
})
pro.then((res)=>{
console.1og("奖金1",res)
//如果return非promise类型,pending-fulfilled
// 如果return promise类型,根据这个新的promise对象的结果,决定
// pending-fulfilled pending-rejected
return res
}).then((res)=>{
console.1og("奖金2",res)
})catch((err)=>{
console.log("没有",err)
})

2.5 Promise.all

let pro1 = new Promise(function(resolve,reject)
//执行器函数
setTimeout(()=>
resoLve(1000)
},1000)
})
let pro2 = new Promise(function(resolve,reject)
//执行器函数
setTimeout(()=>
resoLve(2000)
},2000)
})
let pro3 = new Promise(function(resolve,reject)
//执行器函数
setTimeout(()=>
resoLve(3000)
},3000)
})
Promise.all([pro1,pro2,pro3]).then(res=>{
// 例如对hideloading的处理
console.log(res)
}).catch(err=>{
console.log(err)
})

等到pro1,pro2,pro3 都有结果了之后再去打用相应的回调。

2.6 Promise.race

let pro1 = new Promise(function(resolve,reject)
//执行器函数
setTimeout(()=>
resoLve(1000)
},1000)
})
let pro2 = new Promise(function(resolve,reject)
//执行器函数
setTimeout(()=>
resoLve(2000)
},2000)
})
let pro3 = new Promise(function(resolve,reject)
//执行器函数
setTimeout(()=>
resoLve(3000)
},3000)
})
Promise.race([pro1,pro2,pro3]).then(res=>{
// 例如对hideloading的处理
console.log(res)
}).catch(err=>{
console.log(err)
})

无论pro1,pro2,pro3 哪一个有结果了,程序就会执行对应的回调。

这一般是开发时将程序连接在三个服务器上,如果有服务器瘫痪,但只要有一个服务器健在就可以接收到数据,完成程序的执行。

我们也可以用这个来做服务器超时处理,因为Promise.race 是谁快执行谁。

3. Generator 函数

Generator 函数 – 生成器函数
Generator函数是ES6提供的一种异步编程解决方案
Generator函数是一个状态机,封装了多个内部状态。
执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。
用同步代码去编程异步代码

3.1 基本语法

// * 在function 后面或者 gen后面或者两者之间都可以
function *gen(){
console.log(11)
yield "aaa"//产出
console.log(22)
yield "bbb"
console.1og(33)
Let g gen()
g.next()
g.next()
g.next()

// 11
// 22
// 33
函数遇到yeild 会停止执行下面的代码,只有使用next() 才可以向下执行一步。

g.next() 就是yeild 产出的值

let res1 = g.next()
console.log(res1)
let res2 = g.next()
console.log(res2)
let res3 = g.next()
console.log(res3)
// return ...

在这里插入图片描述
对g 进行遍历得到的结果是
// aaa
// bbb

如果函数中存在return 语句,for…of 循环不会遍历得到return 的结果,因为res3 = {value: ‘ccc’,done: true},根据迭代器的知识判断为true 时程序就停止了,不会得到return 的值。

3.2 手动版本函数

function ajax(url){
return new Promise((resoLve,reject)=>{
Let xhr new XMLHttpRequest()
xhr.open("get",url,true)
xhr.send()
xhr.onreadystatechange function(){
if(xhr.readystate===4){
if(xhr.status>=2008&xhr.status<300){
resoLve(JSON.parse(xhr.responseText))
}else{
reject(xhr.responseText)
}
function *gen(){
Let res yield ajax("1.json")
console.log("第一个请求的结果",res)
Let res2 yield ajax("2.json",res)
console.1og("第一个请求的结果",res2)
Let g gen()
//手动版本
/console.1og()
g.next().value.then(data=>{
/console.log(data)
g.next(data).value.then(res=>{
g.next(res)
})

3.3 自动版本函数

自动版本函数必须保证产出的是一个Promise 对象。

function AutoRun(gen)
Let g gen();
function next(data)
Let res g.next(data);
if (res.done)return
res.value.then(function (data){
next(data);
})next();
}
AutoRun(gen)

4. Class 语法

4.1 类的写法

传统构造函数写法:

function Person(name,age){
this.name = name
this.age = age
// prototype 原型
Person.prototype.say function(){
console.log(this.name,this.age)
Let obj = new Person("kerwin",100)
console.log(obj)

ES6写法:
本质上还是传统函数原型

cLass Person{
constructor(name,age){
this.name = name
this.age = age
}
say(){
console.log(this.name,this.age)
Let obj = new Person("kerwin",100)
console.log(obj)

4.2 get() / set() 拦截用法

cLass Person{
constructor(name,age,location){
this.name = name;
this.age = age;
this.location = location
get location(){
console.log("get")
// return this.location
}
set location(data){
console.log("set",data)
let obj = new Person("kerwin",100,"dalian")

get() 存在return 语句会得到下图所示结果:
在这里插入图片描述
set() 中添加this.location = data 会得到下图所示效果:
在这里插入图片描述
给obj 设置以下操作可恶意使访问obj.html 就可以在html 中生成DOM节点

{
get html(){
return this.ele.innerHTML
}
set html(data){
this.ele.innerHTML = data.map(item=>`<li>${item}</li>`).join
(")}
}
Let obj = new Person("kerwin",100,"list")

4.3 类的静态属性和方法

cLass Person{
// 现在的写法:静态属性和方法
static myname = "person类的名字"
static mymethod = function(){
// console.log("mythod",this.age
}
constructor(name,age){
this.name = name
this.age = age
say(){
console.log(this.name,this.age)
}
// 以前的写法:
// Perpson.myname="person类的名字"
// Person.mymethod function(){
// console.log("mymethod")
// }

5. Class 继承

5.1 基本语法

cLass Student extends Person{
constructor(name,age,score){
super(name,age) // 必写
this.score = score}
}
let obj = new Student("kerwin",100,150)

父类方法的继承:
使用super关键字。

父类和子类中含有相同的方法时(子类方法会覆盖父类方法)实行就近原则,即一般情况下输出子类代码。

子类中含有和父类相同的代码部分,可以通过super关键字进行调用,再添加子类自己的代码。

say(){
super.say()
console.log(this.score)
}

父类中的静态属性和方法也会被子类继承,子类中重新设置相同的属性和方法会覆盖父类数据。

5.2 利用面向对象思想渲染页面

<div class="box1">
<h1></h1>
<u1></u1>
</div>
<script>
var data1 =
title:"体育",
1ist:["体育-1""体育-2""体育-3"]
cLass CreatBox{
constructor(select,data){
this.ele = document.querySelector(seLect)
this.titie = data.title
this.list = data.list
this.render()
}
render(){
let oh1 = this.ele.querySelector("h1")
let oul = this.ele.querySelector("ul")
oh1.innerHTML = this.title
oul.innerHTML = this.list.map(item=>
`<1i>${item}</1i>`
).join("")
}
}
new CreatBox(".box1", data1)
</script>
var data2 = {
title:"综艺"url:"1.png",
1ist:["综艺-1""综艺-2""综艺3"]
}
cLass createlmgBox extends creatBoxt
constructor(seLect,data){
super(seLect,data)
this.imgUrl = data.url
}
render(){
super.render()
let oimg = this.ele.querySelector("img")
oimg.src=this.imgUrl}
}
new CreateImgBox(".box2",data2)

效果展示:
在这里插入图片描述

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

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

相关文章

Android Studio学习5——布局layout与视图view

wrap_content&#xff0c;内容有多大&#xff0c;就有多宽&#xff08;包裹&#xff09; 布局 padding 边框与它自身的内容 margin 控件与控件之间

This app has no Android key hashes configured. . Configure your app key

Unity 接入 Facebook SDK 的过程中遇到这个问题&#xff0c;查了很多帖子&#xff0c;不太直观&#xff0c;记录下来方便需要的同学参考 报上面错误的原因是在https://developers.facebook.com/apps/ 设置里没有填入有效的密钥 怎么填入这个密钥呢&#xff0c;其实很简单&…

Redis性能管理及集群三种模式(一)

一、前期准备 至少准备三台服务器为主从复制、哨兵的实验做准备 一台主redis、两台从redis 二、Redis性能管理 2.1 查看Redis内存使用 查看Redis内存使用——info memory 2.2 内存使用率 1<内存碎片<1.5表示合理的内存碎片大于>1.5&#xff0c;需要输入shutdown save…

创建vue3项目及基本常用配置

1、创建vue3项目 1.1 创建vue3项目 确保电脑中安装了nodejs&#xff0c;新建文件夹&#xff0c;输入以下命令&#xff1a; npm create vuelatest 看是否为自己需要的vue版本&#xff0c;选择Y 各配置具体如下&#xff0c;根据自己的需求选择是或者否 npm create vuelatest …

阿里云数据库服务器价格表查询,一键查询报价

阿里云数据库服务器价格表&#xff0c;优惠99元一年起&#xff0c;ECS云服务器2核2G、3M固定带宽、40G ESSD Entry云盘&#xff0c;优惠价格99元一年&#xff1b;阿里云数据库MySQL版2核2G基础系列经济版99元1年、2核4GB 227.99元1年&#xff0c;云数据库PostgreSQL、SQL Serve…

OpenHarmony实战:标准系统移植指南

本文描述了移植一块开发板的通用步骤&#xff0c;和具体芯片相关的详细移植过程无法在此一一列举。后续社区还会陆续发布开发板移植的实例供开发者参考。 定义开发板 本文以移植名为MyProduct的开发板为例讲解移植过程&#xff0c;假定MyProduct是MyProductVendor公司的开发板…

RC滤波电路

RC滤波电路 综述&#xff1a;本文简单讲述了RC低通滤波电路和RC高通滤波电路。 滤波电路是指过滤输入信号中不需要的信号&#xff0c;保留需要的信号。 一、RC低通滤波电路 1.定义&#xff1a;RC低通滤波电路&#xff1a;保留低频信号&#xff0c;衰减高频信号。 2.截止频率…

突破校园网限速:使用 iKuai 多拨分流负载均衡 + Clash 代理(内网带宽限制通用)

文章目录 1. 简介2. iKuai 部署2.1 安装 VMware2.2 安装 iKuai(1) 下载固件(2) 安装 iKuai 虚拟机(3) 配置 iKuai 虚拟机(4) 配置 iKuai(5) 配置多拨分流 2.3 测试速度 3. Clash 部署3.1 准备工作(1) 配置磁盘分区(2) 安装 Docker(3) 安装 Clash(4) 设置代理 1. 简介 由于博主…

014——超声波模块驱动开发Plus(基于I.MX6uLL、SR04和poll机制)

目录 一、基础知识 二、分析为什么打印会影响中断 三、驱动程序 四、应用程序 五、验证及其它 一、基础知识 013——超声波模块驱动开发&#xff08;基于I.MX6uLL与SR04&#xff09;-CSDN博客 二、分析为什么打印会影响中断 asmlinkage __visible int printk(const ch…

一条SQL查询语句是如何执行的

这是专栏的第一篇文章&#xff0c;我想来跟你聊聊 MySQL 的基础架构。我们经常说&#xff0c;看一个事儿千万不要直接陷入细节里&#xff0c;你应该先鸟瞰其全貌&#xff0c;这样能够帮助你从高维度理解问题。同样&#xff0c;对于 MySQL 的学习也是这样。平时我们使用数据库&a…

Windows11安装MySql-8.0.36安装详细教程(保姆级教程)

之前一直用的mysql5.7&#xff0c;最近导入一个项目一直报错&#xff0c;经查阅发现数据库mysql版本太老&#xff0c;今天特地重头下载安装配置一下&#xff0c;做个记录供大家参考。 下载安装包&#xff1a; 下载地址&#xff1a;https://dev.mysql.com/downloads/ 进入后选…

C++STL--排序算法

sort 使用快速排序,平均性能好O(nlogn),但最差情况可能很差O(n^2)。不稳定。 sort(v.begin(),v.end());//对v容器进行排序,默认升序 sort(v.begin(),v.end(),greater<int>());//降序排序对于支持随机访问的迭代器的容器&#xff0c; 都可以利用sort算法直接对其进行排序…

基于SSM的师生交流平台

目录 背景 技术简介 系统简介 界面预览 背景 传统的师生互动平台主要依赖于面对面的线下交流&#xff0c;用户必须亲自到场以获取和交流相关信息。然而&#xff0c;随着信息技术的广泛传播&#xff0c;众多教育机构开始转向线上发展&#xff0c;寻求更多样化的发展途径。线…

C++11:声明 初始化

C11&#xff1a;声明 & 初始化 初始化{ }初始化initializer_list 声明autodecltypenullptr 初始化 { }初始化 在C98中&#xff0c;允许使用花括号{ }对数组或者结构体元素进行统一的列表初始化。 用{ }初始化数组&#xff1a; int arr[] { 1, 2, 3, 4, 5 };用{ }初始化…

详解2024年阿里云服务器租用价格表,最新报价

阿里云服务器租用价格表2024年最新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核…

C++中的List容器用法详解

文章目录 C中的List容器用法详解List 的特点List 的重要接口用法介绍1.创建和初始化Listlist 2.插入元素push_backpush_forntinsert 删除元素pop_backpop_fontclearerase 遍历List迭代器遍历范围for遍历 排序Listsort 反转Listreverse 转移Listsplice 去重unique 合并merge 总结…

网站可扩展架构设计——中台

从公众号转载&#xff0c;关注微信公众号掌握更多技术动态 --------------------------------------------------------------- 一、中台简介 1.传统项目架构的痛点 (1)重复造轮子 各项目相对独立&#xff0c;许多项目在重复造轮子&#xff0c;让项目本身越来越臃肿&#xf…

[Leetcode笔记] 动态规划相关

前言 写题目写到了一些和动态规划相关的内容&#xff0c;所以在这里记录一下 LCR 089 题解思路 总的来说&#xff0c;就是用一个数组去存储当前的最优解&#xff0c;然后从0开始一路向上顺推过去&#xff0c;求得最后一位的最优解。 class Solution { public:int rob(vect…

检测头篇 | 利用RT-DETR模型的检测头去替换YOLOv8中的检测头

前言:Hello大家好,我是小哥谈。RT-DETR号称是打败YOLO的检测模型,其作为一种基于Transformer的检测方法,相较于传统的基于卷积的检测方法,提供了更为全面和深入的特征理解,将RT-DETR检测头融入YOLOv8,我们可以结合YOLO的实时检测能力和RT-DETR的深度特征理解能力,打造出…

VLAN基础讲解+不同VLAN间通信(实验)

第一章 VLAN基础 1.1 什么是VLAN 随着网络中计算机的数量越来越多&#xff0c;传统的以太网络开始面临广播泛滥以及安全性无法保证等各种问题。 VLAN即虚拟局域网&#xff0c;是将一个物理的局域网在逻辑上划分成多个广播域的技术。通过在交换机上配置VLAN&a…