什么是ES6
ECMAScript的第六个版本:在不改变原理的基础上,尽量简化了代码
一、let
es6中let替代了var,用于声明变量用的关键词
那么var用的好好的为什么es6中要用let来代替那,现在我们来聊一聊var的两个缺点
1.声明提前:打乱了程序正常执行的顺序
2.没有块级作用域:块内的变量很有可能提前到块外部,影响原本正确的外部的程序
比如:if(){}else if(){}else{}
for(){}
while(){}
do{…}while()都是块,但都不是作用域
let的作用
1.阻止声明提前
2.让if(){}else if(){}else{}
for(){}
while(){}
do{…}while()块都变成作用域,块内部的变量无法提升到外部
二、箭头函数
三句话
1.去function,在()和{}之间加=>
2.如果形参列表中只有一个形参,可省略()
3.如果函数体中只有一句话,可省略{}
注意:如果今生一句话,还是return,必须去return
箭头函数的双刃剑:箭头函数中的this,是内外通用的
总结:如果希望内外this一致时,就可改为箭头函数,代替bind,如果不希望内外this相同时,就不可改为箭头函数。比如:对象中的方法不能改箭头,事件处理函数不能改箭头
三、for of
快速遍历一个数组的内容的最简化写法
总结:遍历一个数组时
1.for循环
for(var i=0;i<arr.length;i++){
arr[i]//获取当前数组元素
}
//最灵活的遍历,可以控制遍历的顺序,也可控制遍历的步调
2.forEach简化
arr.forEach(elem,i)=>{
elem//当前数组元素
}
//问题:只能从头到尾一次遍历每个元素,不能控制顺序(从后向前或从前向后)和步调
//如果即关系内容,又关心位置,但不会改变遍历的顺序或不掉时推荐使用
3.for of更简化
for(var elem of arr){
//of会一次取出索引数组中的每个元素值
elem//当前数组元素
}
//问题:只能获得元素内容,无法获得元素位置
//仅关心元素内容时,采用for of
总结:vs for in
使用场合:for of 专门遍历索引数组
for in 专门遍历管理数组
of vs in
of只取元素值
in只取属性
四、参数增强
1.默认值
ES6中可以对形参列表中的最后一个形参设置默认值
什么时候:如果只有最后一个形参不确定时
function find(arr,elem,starti=0){
//如果没有给starti传参,则自动用0代替!
console.log(`在arr中,从${starti}位置开始,找下一个${elem}出现的位置`)
}
find(arr,3);//从0位置开始
find(arr,3,5);//从5位置开始找
2.剩余参数:代替arguments
什么是:让函数可以自动收集结尾多个不确定的参数值
何时:如果在函数形参的结尾,有不确定个数的参数值传入,则可用剩余参数方式收集
为什么:argumens两大缺点
①、不是纯正的数组类型类型对象,数组家的API一个都不能用
②、只能收集所有参数值,无法有选择的收集部分参数值
如何:两步
①、再定函数时,在可以确定的形参后添加“…数组名”
②、在函数内,“数组名”数组中,就自动收集了除已经确定的形参之外的剩余实参值
//定义函数时:
function calc(ename,...arr){
}
//调用时
calc("lilei",1000,2000,3000);
//...arr[1000,2000,3000]
优点:①.可选择的获得部分实参值
②.arr是纯正的数组,数组家的API可以随便用
3.打散数组
代替apply,专门用于打散数组类型的参数
何时:只要函数需要多个零散的参数值,但给定的参数值确是放在一个数组中传入的,发生不一致,就要打散数组
比如:Math.max(arr)不支持数组中查找最大
传统:可用apply打散数组类型参数为单个值
console.log(Math。max.apply(null,nums));
//apply的第一个参数,即没用,又必须写
解决:用…
console.log(Math.max(...nums))
//...先将nums数组打散为单个值,再陆续传给max
总结:①如果在定义函数时,形参列表中…arr,是手机剩余参数保存到数组的意思
②如果在调用函数时,在实参列表中…arr,作用是相反的,是打散数组为单个值,再传入
4.解构
什么是:提取出一个大对象中的部分成员单独使用
何时:如果只使用一个大对象中的一小部分成员时
三种情况
①:数组解构:下标对下标
②:对象结构:属性对属性
③:参数结构:
什么是参数结构:在向函数中传参时,将一个大的对象,打散后,传递给对应的形参变量
何时:多个形参不确定时,又要求按顺序传入
为什么:①默认值,只能应对结尾一个采纳数不确定时
②剩余参数:虽然可应对多个参数不确定的情况,但无法规定传入参数的顺序
总结:当多个形参不确定是,且每个实参值必须对位传给指定的形参变变量
如何解决:
①定义形参时:所有的形参变量都要定义在一个对象结构中
②调用函数传参时,所有实参值,都要放在一个对象结构中整体传入
总结:参数结构,其实就是对象结构在传参时的应用
5.OOP
- 对对象直接量的简写 2处
1.如果对象的成员值来自外部的变量,且属性名和变量名相同时,可只写一个
2.对象直接量中方法的定义不需要加":function"
6.class
用途:描述一类事物统一属性结构和功能的程序结构
本质:其实就是以前的构造函数+原型对象的整体
为什么:因为构造函数和原型对象分开的写法不符合封装的含义
直接上代码
//1.用class{}包裹构造函数和原型对象方法
class Student{
//2.构造函数名提升成类型名,所有构造函数更名为constructor
constructor(sname,sage){
this.sname=sname;
this.sage=sage;
}
//3.所有方法不再需要prototype前缀,不再需要=function
intr(){
console.log(`我叫${this.sname},我今年${this.sage}`)
}
}
7.class之间的继承
问题:两种类型之间存在部分相同的属性结构和方法定义,代码可能出现重复编写
class Enemy{
//抽象父类型构造函数中集中保存所有子类型共有的属性部分
constructor(fname,speed){
this.fname=fname;
this.speed=speed;
}
//抽象父类型原型对象中集中保存所有子类型共有的方法
fly(){
console.log(`${this.fname}以时速${this.speed}飞行`);
}
}
//子类型必须继承(extends)父类型,才能获得父类型中的方法
class Plane extends Enemy{
//子类型构造函数中
constructor(fname,speed,score){
//先借用父类型构造函数(super)帮忙添加共有的属性部分
super(fname,speed);//Enemy中的constructor()
//再自己添加本类型自由的独特的数字那个
this.score=score
}
//Prototypr中:只定义自己类型特有的方法即可,不必定义相同的方法
getScore(){
consoel.log(`击落${this.fname}得${this.score}分`);
}
}
class Bee{
constructor(fname,speed,award){
this.award=award;
}
getAward(){
console.log(`击落${this.fname}获得${this.award}奖励`)
}
}
8.Promise
什么是:专门实现异步函数,顺序执行的一种机制
可以避免回调地狱
多个异步函数,必须顺序执行时
2步
①定义异步函数内
function ming(){
return new Promise(function(open)){
ming要执行的所有代码(包含异步代码)
//当ming的任务执行完,自动打开open()
//当open(),自动执行下一个then中的函数
}
}
②多个支持promise的异步函数,用.then串联起来
ming().then(uzi).then(mlxg).then(xiaohu).then(letme)(function(){结束});