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

2024-04-04 01:20

本文主要是介绍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)

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

这篇关于ES6学习(四)-- Reflect / Promise / Generator 函数 / Class的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/874469

相关文章

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

python中update()函数的用法和一些例子

《python中update()函数的用法和一些例子》update()方法是字典对象的方法,用于将一个字典中的键值对更新到另一个字典中,:本文主要介绍python中update()函数的用法和一些... 目录前言用法注意事项示例示例 1: 使用另一个字典来更新示例 2: 使用可迭代对象来更新示例 3: 使用

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

Python lambda函数(匿名函数)、参数类型与递归全解析

《Pythonlambda函数(匿名函数)、参数类型与递归全解析》本文详解Python中lambda匿名函数、灵活参数类型和递归函数三大进阶特性,分别介绍其定义、应用场景及注意事项,助力编写简洁高效... 目录一、lambda 匿名函数:简洁的单行函数1. lambda 的定义与基本用法2. lambda

Python 函数详解:从基础语法到高级使用技巧

《Python函数详解:从基础语法到高级使用技巧》本文基于实例代码,全面讲解Python函数的定义、参数传递、变量作用域及类型标注等知识点,帮助初学者快速掌握函数的使用技巧,感兴趣的朋友跟随小编一起... 目录一、函数的基本概念与作用二、函数的定义与调用1. 无参函数2. 带参函数3. 带返回值的函数4.