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

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...