Web开发

注册

 

发新话题 回复该主题

web前端培训ES6ES12的开发技巧 [复制链接]

1#
北京治疗白癜风哪家医院不错 https://wapjbk.39.net/yiyuanzaixian/bjzkbdfyy/

以下文章来源于前端之神

ES6

1、let和const

这两个的出现,总感觉是为了开发的代码规范而出现的。我们要逐渐放弃var,在项目中多用let和const

与var的区别:

var有变量提升,有初始化提升,值可变

let有变量提升,没有初始化提升,值可变

const有变量提升,没有初始化提升,值不可变,但如果是定义对象,则属性可变

暂时性死区问题说明:其实let和const是有变量提升的,但是没有初始化提升:

varname=林三心

functionfn(){

console.log(name)

letname=sunshin_lin

}

fn()//Cannotaccessnamebeforeinitialization

块级作用域解决问题:

for(vari=0;i5;i++){

setTimeout(()={

console.log(i)

})

}//

for(leti=0;i5;i++){

setTimeout(()={

console.log(i)

})

}//

2、默认参数

开发中你曾遇到过这样的问题,如果参数不传进来,你就设置默认参数

functionfn(name,age){

varname=name

林三心

varage=age

18

console.log(name,age)

}

fn()//林三心18

但是这么写确实不优雅,可以使用ES6的默认参数

functionfn(name=林三心,age=18){

console.log(name,age)

}

fn()//林三心18

fn(sunshine,22)//sunshine22

3、扩展运算符

曾经的我,想要拼接多个数组,我只能这么做

constarr1=[1,2,4]

constarr2=[4,5,7]

constarr3=[7,8,9]

constarr=arr1.concat(arr2).concat(arr3)

[

1,2,4,4,5,

7,7,8,9

]

现在的我,可以更优雅地进行拼接

constarr1=[1,2,4]

constarr2=[4,5,7]

constarr3=[7,8,9]

constarr=[...arr1,...arr2,...arr3]

[

1,2,4,4,5,

7,7,8,9

]

4、剩余参数

大家可能遇到过这种问题,一个函数,传入参数的个数是不确定的,这就可以用ES6的剩余参数

functionfn(name,...params){

console.log(name)

console.log(params)

}

fn(林三心,1,2)//林三心[1,2]

fn(林三心,1,2,3,4,5)//林三心[1,2,3,4,5]

5、模板字符串

以前的我,拼接字符串只能这么做

constname=林三心

constage=22

console.log(name+今年+age+岁啦)//林三心今年22岁啦

现在我可以这么做,会更优雅

constname=林三心

constage=22

console.log(`${name}今年${age}岁啦`)//林三心今年22岁啦

6、Object.keys

可以用来获取对象的key的集合,进而可以获得对应key的value

constobj={

name:林三心,

age:22,

gender:男

}

constkeys=Object.keys(obj)

console.log(keys)//[name,age,gender]

7、箭头函数

以前我们使用普通函数

functionfn(){}

constfn=function(){}

ES6新加了箭头函数

constfn=()={}

//如果只有一个参数,可以省略括号

constfn=name={}

//如果函数体里只有一句return

constfn=name={

return2*name

}

//可简写为

constfn=name=2*name

//如果返回的是对象

constfn=name=({name:name})

普通函数和箭头函数的区别:

1、箭头函数不可作为构造函数,不能使用new

2、箭头函数没有自己的this

3、箭头函数没有arguments对象

4、箭头函数没有原型对象

8、Array.forEach

ES6新加的数组遍历方法

consteachArr=[1,2,3,4,5]

//三个参数:遍历项索引数组本身

//配合箭头函数

eachArr.forEach((item,index,arr)={

console.log(item,index,arr)

})

10[1,2,3,4,5]

21[1,2,3,4,5]

32[1,2,3,4,5]

43[1,2,3,4,5]

54[1,2,3,4,5]

9、Array.map

常用于返回一个处理过后的新数组

constmapArr=[1,2,3,4,5]

//三个参数:遍历项索引数组本身

//配合箭头函数,对每一个元素进行翻倍

constmapArr2=mapArr.map((num,index,arr)=2*num)

console.log(mapArr2)

[2,4,6,8,10]

10、Array.filter

顾名思义,用来过滤的方法

constfilterArr=[1,2,3,4,5]

//三个参数:遍历项索引数组本身

//配合箭头函数,返回大于3的集合

constfilterArr2=filterArr.filter((num,index,arr)=num3)

console.log(filterArr2)

[4,5]

11、Array.some

some,意思就是只有一个是真,那就返回真

constsomeArr=[false,true,false,true,false]

//三个参数:遍历项索引数组本身

//配合箭头函数,只要有一个为true,就返回true,一个都true都没有,就返回false

constsomeArr2=someArr.some((bol,index,arr)=bol)

console.log(someArr2)

true

12、Array.every

every跟some是相反的,some是只有一个就行,every是要所有为真才返回真

consteveryArr=[false,true,false,true,false]

//三个参数:遍历项索引数组本身

//配合箭头函数,需要所有为true,才返回true,否则返回false

consteveryArr2=everyArr.every((bol,index,arr)=bol)

console.log(everyArr2)

13、Array.reduce

第一个参数callback函数:pre为上次return的值,next为数组的本次遍历的项

第二个参数为初始值,也是第一个pre

举两个例子:

//计算1+2+3+4+5

constreduceArr=[1,2,3,4,5]

constsum=reduceArr.reduce((pre,next)={

returnpre+next

},0)

console.log(sum)//15

//统计元素出现个数

constnameArr=[林三心,sunshine_lin,林三心,林三心,科比]

consttotalObj=nameArr.reduce((pre,next)={

if(pre[next]){

pre[next]++

}else{

pre[next]=1

}

returnpre

},{})

console.log(totalObj)//{林三心:3,sunshine_lin:1,科比:1}

14、对象属性同名简写

以前同名属性需要这么写

constname=林三心

constage=22

constobj={

name:name,

age:age

}

console.log(obj)//{name:林三心,age:22}

ES6新增语法,只需这么写

constname=林三心

constage=22

//属性同名可简写

constobj={

name

age

}

console.log(obj)//{name:林三心,age:22}

15、Promise

Promise,中文名为承诺,承诺在哪呢?承诺在,一旦他的状态改变,就不会再改。这里就介绍基本使用,如果想要深入理解如何使用,请看我的另一篇文章看了就会,手写Promise原理,最通俗易懂的版本!!!

看看基本使用

成功状态

functionrequestData(){

//模拟请求

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(林三心)

},)

})

}

requestData().then(res={

console.log(res)//一秒钟后输出林三心

},err={

console.log(err)

})

失败状态

functionrequestData(){

//模拟请求

returnnewPromise((resolve,reject)={

setTimeout(()={

reject(错误啦)

},)

})

}

requestData().then(res={

console.log(res)

},err={

console.log(err)//一秒钟后输出错误啦

})

all方法

接收一个Promise数组,数组中如有非Promise项,则此项当做成功

如果所有Promise都成功,则返回成功结果数组

如果有一个Promise失败,则返回这个失败结果

//如果全都为成功

functionfn(time){

returnnewPromise((resolve,reject)={

console.log(88)

setTimeout(()={

resolve(`${time}毫秒后我成功啦!!!`)

},time)

})

}

Promise.all([fn(),fn(),fn()]).then(res={

//3秒后输出[毫秒后我成功啦!!!,毫秒后我成功啦!!!,毫秒后我成功啦!!!]

console.log(res)

},err={

console.log(err)

})

//如果有一个失败

functionfn(time,isResolve){

returnnewPromise((resolve,reject)={

setTimeout(()={

isResolve?resolve(`${time}毫秒后我成功啦!!!`):reject(`${time}毫秒后我失败啦!!!`)

},time)

})

}

Promise.all([fn(,true),fn(),fn(,true)]).then(res={

console.log(res)

},err={

console.log(err)//3秒后输出毫秒后我失败啦!!!

})

race方法

接收一个Promise数组,数组中如有非Promise项,则此项当做成功

哪个Promise最快得到结果,就返回那个结果,无论成功失败

functionfn(time,isResolve){

returnnewPromise((resolve,reject)={

setTimeout(()={

isResolve?resolve(`${time}毫秒后我成功啦!!!`):reject(`${time}毫秒后我失败啦!!!`)

},time)

})

}

Promise.race([fn(,true),fn(),fn()]).then(res={

console.log(res)

},err={

console.log(err)//1秒后输出

})

16、class

以前咱们使用构造函数生成对象,这么做

functionPerson(name){

this.name=name

}

Person.prototype.sayName=function(){

console.log(this.name)

}

constkobe=newPerson(科比)

kobe.sayName()//科比

而有了ES6的class可以这么做

classPerson{

constructor(name){

//构造器

this.name=name

}

sayName(){

console.log(this.name)

}

}

constkobe=newPerson(科比)

kobe.sayName()//科比

值得一提的是,class本质也是function,class是function的语法糖

classPerson{}

console.log(typeofPerson)//function

除了以上,还需要知道class的以下知识点

静态属性和静态方法,使用static定义的属性和方法只能class自己用,实例用不了

classPerson{

constructor(name){

this.name=name

}

staticage=22

staticfn(){

console.log(哈哈)

}

}

console.log(Person.age)//22

Person.fn()//哈哈

constsunshine_lin=newPerson(林三心)

console.log(sunshine_lin.age)//undefined

sunshine_lin.fn()//fnisnotafunction

extend继承

classAnimal{

constructor(name,age){

this.name=name

this.age=age

}

}

classCatextendsAnimal{

say(){

console.log(this.name,this.age)

}

}

constcat=newCat(ketty,5)//继承了Animal的构造器

cat.say()//ketty5

17、解构赋值

以前想提取对象里的属性需要这么做

constobj={

name:林三心,

age:22,

gender:男

}

constname=obj.name

constage=obj.age

constgender=obj.gender

console.log(name,age,gender)//林三心22男

ES6新增了解构赋值的语法

constobj={

name:林三心,

age:22,

gender:男,

doing:{

morning:摸鱼,

afternoon:摸鱼,

evening:sleep

}

}

const{name,age,gender}=obj

console.log(name,age,gender)//林三心22男

//解构重名

const{name:myname}=obj

console.log(myname)//林三心

//嵌套解构

const{doing:{evening}}=obj

console.log(evening)//sleep

也可以进行数组的解构

constarr=[1,2,3]

const[a,b,c]=arr

console.log(a,b,c)//

//默认赋值

const[a,b,c,d=5]=arr

console.log(a,b,c,d)//5

//乱序解构

const{1:a,0:b,2:c}=arr

console.log(a,b,c)//

18、find和findIndex

find:找到返回被找元素,找不到返回undefined

findIndex:找到返回被找元素索引,找不到返回-1

constfindArr=[

{name:科比,no:24},

{name:罗斯,no:1},

{name:利拉德,no:0}

]

constkobe=findArr.find(({name})=name===科比)

constkobeIndex=findArr.findIndex(({name})=name===科比)

console.log(kobe)//{name:科比,no:24}

console.log(kobeIndex)//0

19、forof和forin

forin:遍历方法,可遍历对象和数组

forof:遍历方法,只能遍历数组,不能遍历对象先看forin:

constobj={name:林三心,age:22,gender:男}

constarr=[1,2,3,4,5]

for(letkeyinobj){

console.log(key)

}

name

age

gender

for(letindexinarr){

console.log(index)

}

再看forof:

for(letitemofarr){

console.log(item)

}

45

20、Set和Map

Set先说说Set的基本用法

//可不传数组

constset1=newSet()

set1.add(1)

set1.add(2)

console.log(set1)//Set(2){1,2}

//也可传数组

constset2=newSet([1,2,3])

//增加元素使用add

set2.add(4)

set2.add(林三心)

console.log(set2)//Set(5){1,2,3,4,林三心}

//是否含有某个元素使用has

console.log(set2.has(2))//true

//查看长度使用size

console.log(set2.size)//5

//删除元素使用delete

set2.delete(2)

console.log(set2)//Set(4){1,3,4,林三心}

再说说Set的不重复性

//增加一个已有元素,则增加无效,会被自动去重

constset1=newSet([1])

set1.add(1)

console.log(set1)//Set(1){1}

//传入的数组中有重复项,会自动去重

constset2=newSet([1,2,林三心,3,3,林三心])

console.log(set2)//Set(4){1,2,林三心,3}

Set的不重复性中,要注意引用数据类型和NaN

//两个对象都是不用的指针,所以没法去重

constset1=newSet([1,{name:林三心},2,{name:林三心}])

console.log(set1)//Set(4){1,{name:林三心},2,{name:林三心}}

//如果是两个对象是同一指针,则能去重

constobj={name:林三心}

constset2=newSet([1,obj,2,obj])

console.log(set2)//Set(3){1,{name:林三心},2}

咱们都知道NaN!==NaN,NaN是自身不等于自身的,但是在Set中他还是会被去重

constset=newSet([1,NaN,1,NaN])

console.log(set)//Set(2){1,NaN}

利用Set的不重复性,可以实现数组去重

constarr=[1,2,3,4,4,5,5,66,9,1]

//Set可利用扩展运算符转为数组哦

constquchongArr=[...newSet(arr)]

console.log(quchongArr)//[1,2,3,4,5,66,9]

MapMap对比object最大的好处就是,key不受类型限制

//定义map

constmap1=newMap()

//新增键值对使用set(key,value)

map1.set(true,1)

map1.set(1,2)

map1.set(哈哈,嘻嘻嘻)

console.log(map1)//Map(3){true=1,1=2,哈哈=嘻嘻嘻}

//判断map是否含有某个key使用has(key)

console.log(map1.has(哈哈))//true

//获取map中某个key对应的value使用get(key)

console.log(map1.get(true))//2

//删除map中某个键值对使用delete(key)

map1.delete(哈哈)

console.log(map1)//Map(2){true=1,1=2}

//定义map,也可传入键值对数组集合

constmap2=newMap([[true,1],[1,2],[哈哈,嘻嘻嘻]])

console.log(map2)//Map(3){true=1,1=2,哈哈=嘻嘻嘻}

ES7

21、includes

传入元素,如果数组中能找到此元素,则返回true,否则返回false

constincludeArr=[1,2,3,林三心,科比]

constisKobe=includeArr.includes(科比)

console.log(isKobe)//true

跟indexOf很像,但还是有区别的

constarr=[1,2,NaN]

console.log(arr.indexOf(NaN))//-1indexOf找不到NaN

console.log(arr.includes(NaN))//trueincludes能找到NaN

22、求幂运算符

以前求幂,我们需要这么写

constnum=Math.pow(3,2)//9

ES7提供了求幂运算符:**

constnum=3**2//9

ES8

23、Object.values

可以用来获取对象的value的集合

constobj={

name:林三心,

age:22,

gender:男

}

constvalues=Object.values(obj)

console.log(values)//[林三心,22,男]

24、Object.entries

可以用来获取对象的键值对集合

constobj={

name:林三心,

age:22,

gender:男

}

constentries=Object.entries(obj)

console.log(entries)

//[[name,林三心],[age,22],[gender,男]]

25、async/await

这个是很常用的语法了,我的理解就是:以同步方式执行异步操作

我们平时可能会遇到这种场景,接口一,请求到数据一,而数据一被当做请求二的参数去请求数据二,我们会用Promise这么做

functionfn(){

//模拟第一次请求

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(5)

},)

}).then(res={

//模拟第二次请求

newPromise((resolve,reject)={

setTimeout(()={

//拿第一次请求的数据去乘10,当做第二次请求的数据

resolve(res*10)

},)

}).then(sres={

console.log(sres)

})

})

}

fn()//1+2=33秒后输出50

这样的嵌套是不美观的,如果有很多个接口,那就会嵌套很多层,此时我们可以使用async/await来以同步方式执行异步,注意以下几点:

await只能在async函数里使用

await后面最好接Promise,如果后面接的是普通函数则会直接执行

async函数返回的是一个Promise

functionfn1(){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(5)

},)

})

}

functionfn2(data){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(data*10)

},)

})

}

asyncfunctionreq(){

//同步方式执行异步,像排队一样

constdata1=awaitfn1()//等待1秒后返回数据再往下执行

constdata2=awaitfn2(data1)//拿data1去请求2秒后,往下走

console.log(data2)//总共3秒后输出50

}

req()

ES9

26、forawaitof

我们来看以下场景哈

functionfn(time){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(`${time}毫秒后我成功啦!!!`)

},time)

})

}

fn().then(res=console.log(res))

fn().then(res=console.log(res))

fn().then(res=console.log(res))

结果是

毫秒后我成功啦!!!

毫秒后我成功啦!!!

毫秒后我成功啦!!!

但是我想要这个结果

毫秒后我成功啦!!!

毫秒后我成功啦!!!

毫秒后我成功啦!!!

第一时间我们肯定想到的是async/await

functionfn(time){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(`${time}毫秒后我成功啦!!!`)

},time)

})

}

asyncfunctionasyncFn(){

//排队

constdata1=awaitfn()

console.log(data1)//3秒后毫秒后我成功啦!!!

constdata2=awaitfn()

console.log(data2)//再过1秒毫秒后我成功啦!!!

constdata3=awaitfn()

console.log(data3)//再过2秒毫秒后我成功啦!!!

}

但是上面代码也是有缺点的,如果有几十个,那不是得写几十个await,有没有一种方法可以通过循环来输出呢?

functionfn(time){

returnnewPromise((resolve,reject)={

setTimeout(()={

resolve(`${time}毫秒后我成功啦!!!`)

},time)

})

}

asyncfunctionasyncFn(){

constarr=[fn(),fn(),fn(),fn(),fn()]

forawait(letxofarr){

console.log(x)

}

}

asyncFn()

毫秒后我成功啦!!!

毫秒后我成功啦!!!

毫秒后我成功啦!!!

毫秒后我成功啦!!!

毫秒后我成功啦!!!

27、Promise.finally

新增的Promise方法,无论失败或者成功状态,都会执行这个函数

//cheng

newPromise((resolve,reject)={

resolve(成功喽)

}).then(

res={console.log(res)},

err={console.log(err)}

).finally(()={console.log(我是finally)})

newPromise((resolve,reject)={

reject(失败喽)

}).then(

res={console.log(res)},

err={console.log(err)}

).finally(()={console.log(我是finally)})

ES10

28、Array.flat

有一个二维数组,我想让他变成一维数组:

constarr=[1,2,3,[4,5,6]]

console.log(arr.flat())//[1,2,3,4,5,6]

还可以传参数,参数为降维的次数

constarr=[1,2,3,[4,5,6,[7,8,9]]]

console.log(arr.flat(2))

[

1,2,3,4,5,

6,7,8,9

]

如果传的是一个无限大的数字,那么就实现了多维数组(无论几维)降为一维数组

constarr=[1,2,3,[4,5,6,[7,8,9,[10,11,12]]]]

console.log(arr.flat(Infinity))

[

1,2,3,4,5,

6,7,8,9,10,

11,12

]

29、Array.flatMap

现在给你一个需求

letarr=["科比詹姆斯安东尼","利拉德罗斯麦科勒姆"];

将上面数组转为

[科比,詹姆斯,安东尼,利拉德,罗斯,麦科勒姆]

第一时间想到map+flat

console.log(arr.map(x=x.split("")).flat());

//[科比,詹姆斯,安东尼,利拉德,罗斯,麦科勒姆]

flatMap就是flat+map,一个方法顶两个

console.log(arr.flatMap(x=x.split("")));

//[科比,詹姆斯,安东尼,利拉德,罗斯,麦科勒姆]

30、BigInt

BigInt是ES10新加的一种JavaScript数据类型,用来表示表示大于2^53-1的整数,2^53-1是ES10之前,JavaScript所能表示最大的数字

分享 转发
TOP
发新话题 回复该主题