首页 > 技术文章 > es6小记

xiaofenguo 2019-08-20 17:34 原文

 

let const

let 定义变量,局部作用域,没有变量提升,只能先定义后使用,不能重复定义

const 定义常量,不能修改,如果定义的是一个对象,让这个对象不能修改,需要使用

Object.freeze(obj);

var 定义的全局变量是属于window的,let const 不同

解构赋值:

两边的结构格式必须一致:

demo1:

let [a,b,c]=[1,2,3];
console.log(a,b,c);//"1" "2" "3"
部分赋值
let [a1,,c1]=[1,2,3];
console.log(a1,c1);//"1"  "3"
 

demo2:

let{name,age,job}={
    name:'zhangsan',age:'12',job:'web'
};
console.log(name,age,job);//"zhangsan" "12" "web"
 

解构赋值可以重命名:

let{name1:n,age1:g,job1:j}={
    name1:'zhangsan',age1:'12',job1:'web'
};
console.log(n,g,j);//"zhangsan" "12" "web"

可以设置默认值

let [d,e,f=100]=[1,2];
console.log(d,e,f);//1 2 100

交换两个值:

let a=10; 
let b=5;
[a,b]=[b,a];
console.log(a,b);//5,10

对象再次赋值:需要用()包裹,否则会解析为局部作用域

let c='age';
({c}={c:'name'});
console.log(c);//name

字符串模板

let name='zhangsan'; 
let age=15;
console.log(`姓名:${name},年龄:${age}`);//姓名:zhangsan,年龄:15

1  可以随意换行 2 取值 ${}

字符串的方法:

判断是否包含某个字符串

includes() 返回true false

indexOf() 返回索引位置

字符串以谁开始:

startsWith()返回true false

字符串以谁结束:

endsWidth()返回true false

字符号重复:

repeat(次数)//重复的次数

字符号填充:

padStart(字符号长度,填充的字符串)

padEnd(字符号长度,填充的字符串)

函数默认参数 箭头函数 剩余参数

function demo({name='zhangsan',age='18'}={}){
console.log(`姓名:${name},年龄:${age}`);
}
demo();//
demo({name:'lisi'});//姓名:lisi,年龄:18
demo({age:100})//姓名:zhangsan,年龄:18
demo({name:'lisi',age:200});//姓名:lisi,年龄:200

函数的参数默认是定义过的,不能再函数体重重复定义变量

function demo(a){

let a=100;

}

报错,变量重复定义

箭头函数,

1 this问题,定义函数所在的对象,不再是运行时所在的对象(如果不会箭头函数,this执行运行时所在的对象)

2 箭头函数内没有arguments,使用...

3 箭头函数不能用于构造函数

demo

function demo3(){
    let obj= {
        id:2,
        show:function(){
           setTimeout(function(){ alert(this.id);},1000);
        }
    };
    return obj;
}
demo3().show()//undefined setTimeout是window执行的,所以this指向winidow


function demo3(){
    let obj= {
        id:2,
        show:function(){
           setTimeout(()=>{ alert(this.id);},1000);
        }
    };
    return obj;
}
demo3().show()//2  箭头函数,this指向定义时的对象,就是obj

 

... 扩展运算符 Rest运算符

数组

arr.forEach(function(val,idnex,arr){}) 参数是个回调函数,替换普通的for循环

arr.map() 做数据交互映射,重新整理数据解构,正常情况下需要配合return使用,如果没有就和forEach()一样

  注意:平时用到map,就需要用到return 返回一个新的数组

arr.filter()

  过滤一些不合格的元素,如果回调函数返回的是true就留下,false就过滤掉

arr.some()

  遍历数组,类似查找,有一个符合要求就返回true

arr.every()

  遍历数组,所有元素符合要求就返回true,否则返回false

 

以上的方法接收的参数都是一样的,可以接收两个参数,循环回调函数,this指向谁;

也可以使用bind修改this的指向 arr.forEach().bind(123)

 

arr.reduce(function(prev,cur,index,arr){})  从左到右

    求数组的和prev:上次循环的结果,cur当前的值,index当前值得索引,arr数组本身

 

demo:

[1,2,3,4,5].reduce((prev,cur,index,arr)=>{return pre+cur})//15

arr.reduceRight()  从右到左

 

 

for...of....

可以用来循环数组和对象   arr.keys() arr.entries()

 Array.from:

  把类数组转换成数组,类数组需要有length属性

  如果是数组,直接复制数组

demo:

let arr=[1,2,3,4,5];
console.log(Array.from(arr));//[1,2,3,4,5]

let json={
  0:'zahngsan',
  1:'lisi',
  2:'wangwu'
}; 
console.log(Array.from(json//[]

let json={
  0:'zahngsan',
  1:'lisi',
  2:'wangwu',
  length:3
}; 
console.log(Array.from(json//['zhangsan','lisi','wangwu']

let json
={   0:'zahngsan',   1:'lisi',   2:'wangwu',   length:2 }; console.log(Array.from(json//['zhangsan','lisi']

Array.of()   :把一组值转为数组

demo:

console.log(Array.of('1','2','3'));//[1,2,3]

arr.find()     找到第一个符合条件的数组成员,如果没有返回undefined

demo:

let arr=[1,2,3,4,5];
    let bb=arr.find((item,index,arr)=>{
        return item>3;
    });
    console.log(bb);//4
function demo(){
    let arr=[1,2,3,4,5];
    let bb=arr.find((item,index,arr)=>{
        return item>5;
    });
    console.log(bb);//undefined
}

arr.findIndex()  : 找到第一个符合条件的数组成员的索引,如果没有返回-1

function demo1(){
    let arr=[1,2,3,4,5];
    let bb=arr.findIndex((item,index,arr)=>{
        return item>5;
    });
    console.log(bb);//-1
}


function demo2(){
    let arr=[1,2,3,4,5];
    let bb=arr.findIndex((item,index,arr)=>{
        return item>3;
    });
    console.log(bb);//3
}

arr.fill(填充的内容,开始位置,结束位置) 填充数组规定位置的数据

function demo(){
    let arr=[1,2,3,4,5];
    let bb=arr.fill('x',0,2);
    console.log(bb);//['x','x',3,4,5]
}

arr.includes()

对象

对象的简洁语法

let name='zhangsan';
let age=20;
let json={
  name,//name:name
  age//age:age
}

Object.is(值1,值2);比较两个值是否相等

console.log(NaN==NaN);//false

Object.is(NaN,NaN);//true

console.log(N0==-0);//true

Object.is(0,-0);//false

Object.assign(目标对象,source1,source2,...source3) ///合并对象,后面的值覆盖前面的值

作用: 就复制一维对象     合并参数

Object.assign([],[2,3,4,5])//[2,3,4,5]
Object.assign({},{name:'zhangsan'})//{name:'zhangsan'}

Object.keys()   Object.values()  Object.entries()

demo:

let {keys,values,entries}=Object;//解构赋值
let json={name:'zhangsan',age:20};
for(let key in keys(json))console.log(key)//name  age
等价于:
for(let key in Object.keys(json))console.log(key)//name  age

for(let value in values(json))console.log(value)//'zhangsan' 20
等价于:
for(let value in Object.values(json))console.log(value)//'zhangsan' 20

对象的解构赋值...

Promise

作用: 解决异步回调问题

let a=10;
   var promise=new Promise(function(resolve,reject){
       if(a==100){
        resolve('成功');
       }else{
        reject('失败');
   }
   });
      promise.then(res=>{
           console.log(res);
      }).catch(err=>{
        console.log(err);
      });
   

Promise.resolve('aa')//将现有的东西转成一个promise对象,reslove状态,成功状态

Promise.reject('bb')//将现有的东西转成一个promise对象,reject状态,失败状态

let a=Promise.resolve('aaa');
   等价于: a=new Promise((resolve,reject)=>{
            resolve('aaa');
   });
   a.then(res=>{
       console.log(res);
   })
   

   let b=Promise.reject('bbb');
   等价于: b=new Promise((resolve,reject)=>{
    reject('bbb');
});
   b.catch(res=>{
       console.log(res);
   })
   

Promise.all([p1,p2,p3,...])//把promise打包,扔到一个数组里面,打包完之后还是一个Promise对象,必须确保,所有的promise对象,都是resolve状态,都是成功的状态,其中有一个不是就会报错,走的是reject

demo:

let a=Promise.resolve('aaa');
   let b=Promise.resolve('bbb');
   let c=Promise.resolve('ccc');
   Promise.all([a,b,c]).then(res=>{
    console.log(res);//['aaa','bbb','ccc']
   }).catch(err=>{
    console.log(err);
   });


let a1=Promise.resolve('aaa');
let b1=Promise.resolve('bbb');
let c1=Promise.resolve('ccc');
   Promise.all([a1,b1,c1]).then(res=>{
    console.log(res);
   }).catch(err=>{
    console.log(err);//bbb
   });

Promise.race([p1,p2,p3,...])//跟Promise.all()的区别:一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

模块化:

commonjs  主要服务端: nodeJS

AMD     requireJs curJs

CMD    seaJs

1 如何定义模块

2 如何使用模块

使用模块:

<script type='module'></script>

导出模块: export

导入模块:import   路径可以是相对路径也可以是绝对路径,无论导入多少次,只会被导入一次

import  '文件路径'//相当于导入一个文件

demo:

1.js
const a=1;
const b=2;
const c=3;
export{a,b,c}
2.js使用
import {a,b,c} from '1.js'
console.log(a,b,c);// 1 2 3
//名字要一致

变量名可以重命名
1.js
const a=1;
const b=2;
const c=3;
export{a as aaa,b as bbb,c as ccc}
2.js使用
import {aaa as a ,bbb as b,ccc as c} from '1.js'
console.log(a,b,c);// 1 2 3
3.js使用
import {aaa ,bbb,ccc} from '1.js'
console.log(aaa,bbb,ccc);// 1 2 3

导入所有导出的数据

import * as demo from '1.js

1.js
const a=1;
const b=2;
const c=3;
export{a,b,c}
2.js
import * as demo from '1.js'
console.log(demo.a,demo.b,demo.c);//1 2 3

export default 导出的数据,导入的时候不需要{} 

1.js
export default a=10;
2.js
import a from '1.js'
console.log(a)//10



1.js
export default a=10;
export const b=20;
2.js
import a {b} from '1.js'
console.log(a,b)//10 20

import  有提升效果,import会自动提升到顶部,首先执行

导出到模块的内容,如果里面有定时器更换,外面也会改动,不同commonJS的缓存

import() 类似node里面的require,可以动态引入,默认import语法不能写在if之类里面;

import() 可以写在if语句中,可以使用动态路径;路径可以是相对的或者是绝对的;按需加载;返回的是Promise对象可以使用then

demo:

1.js
export const a=10;
export const b=20;
2.js
import('1.js').then(res=>{
    console.log(res.a,res.b);、、10 20
});

结合promise使用

demo:

1.js
export const a=10;
2.js
export cosnt b=20;
3.js
Promise.all([import('1.js'),import('2.js')]).then((mode1,mode2)=>{
    console.log(mode1,mode2);//{a:10} {b:20}
);

class Person{

  constructor(){  //构造函数(方法),调用new,自动执行

  }

}

demo:

class Person{
      constructor(name,age){
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
  }
  new Person('zhangsan',18);//构造函数执行了name:zhangsan,年龄:18

es5 模拟类:

let Person=function(name,age){
        this.name=name;
        this.age=age;
    }   
Person.prototype.showName=function(){
    console.log(this.name);
}     
Person.prototype.showAge=function(){
    console.log(this.age);
}  

es6定义类

class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
      showName(){
          console.log(`name:${this.name}`);
      }
      showAge(){
        console.log(`age:${this.age}`);
    }
  }
  let p=new Person('zhangsan',18);
  console.log(p.showName(),p.showAge());

注意点

1 constructor new时自动调用

2 方法之间没有逗号,间隔

3 方法不能加function关键字

 

类也可以使用变量命名方式

let Person=class{
      constructor(name,age){
          this.name=name;
          this.age=age;
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
      showName(){
          return `name:${this.name}`;
      }
      showAge(){
        return `age:${this.age}`;
    }
  }
  let p=new Person('zhangsan',18);
  console.log(p.showName(),p.showAge());

方法可以使用变量名:

let a='showName';
let b='showAge';
class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
         console.log(`构造函数执行了name:${name},年龄:${age}`);
      }
      [a](){
          return `name:${this.name}`;
      }
      [b](){
        return `age:${this.age}`;
    }
  }
  let p=new Person('zhangsan',18);
  console.log(p.showName(),p.showAge());
console.log(p[a](),p[b]());//与上面的等价

注意点:

es6里面的class没有提升功能,只能先定义再使用,再ES5中,用函数模拟,有提升功能,function本身有提升功能

矫正this

1 fn.call(this指向谁,args1,args2...);

2 fn.apply(this指向谁,args1,args2,...);

3 fn.bind(this指向谁)

 

class里面取值(getter)存值(setter)封装框架会用到

 

静态方法:类身上的方法,直接使用类调用 static,子类可以继承父类的静态方法

demo:

class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
      }
      static aa(){
          return 'this is aa'
      }
      showName(){
          return `name:${this.name}`;
      }
      showAge(){
        return `age:${this.age}`;
    }
  }
  let p=new Person('zhangsan',18);
  console.log(Person.aa());//this is aa,只能用类进行调用,不能用实例调用

类的继承

extends关键字实现

demo:

class Person{
      constructor(name,age){
          this.name=name;
          this.age=age;
      }
      static aa(){
          return 'this is aa'
      }
      showName(){
        console.log('这是父类的showName方法') 
          return `name:${this.name}`;
      }
      showAge(){
        return `age:${this.age}`;
    }
  }
  class Student extends Person{
      constructor(name,age,skill){
          super(name,age);//继承父类的属性name age
          this.skill=skill;
      }
      showName(){
          super.showName();//继承父类的showName方法
          console.log('这是子类的showName方法') 
      }
      showSkill(){
          return  `技能${this.skill}`
      }
  }
  let stu=new Student('zhangsan',18,'学习');
  console.log(stu.showSkill());
 stu.showName();

1 子类定义自己的contructor需要使用super关键字继承父类的属性,然后可以添加自己的属性

2 字类可以定义与父类一样的名字的方法,直接覆盖父类的方法

3 子类继承父类的方法,并添加自己的方法,需要使用super关键字,先继承父类的方法,再写自己的私有方法,这样先执行父类的方法,再执行子类的方法

新增数据类型

number string object function undefined  bollean

symbol 

1 Symbol不能new

2 Symbol() 返回是一个唯一值,做一个key,定义一些唯一或者私有的东西

3 symbol是一个单独数据类型,就叫symbol基本类型

4 如果symbol作为key,用for in循环,出不来(因为是私有的,不显示)

generator函数

  生成器

解决异步的问题,深度嵌套的问题,现在使用asyns

语法:

function * show(){} 在function和方法名之间有一个*号

yield

demo:

function * gen(){

  yield "welcome";

  yield "to";

  return '牧马人'

}

let g1=gen();

使用方法:

手动调用

g1.next();//{value:'welcome',done:false}

g1.next();//{value:'to',done:false}
g1.next();//{value:'牧马人',done:true}
for...of 自动遍历generator

for(let value of g1){

console.log(value);// welcome to

}

return的东西不会遍历

也可以使用解构赋值

let [a,...b]=gen();//a:'welcome' b:to

console.log(...gen)//['welcome','to']

console.log(...gen)//['welcome','to']

generator一般配合promise使用

async和await

async特点:表示的就是异步,这个函数里面有异步任务

await 表示后面结果需要等待

async特点:

1 await只能放在async函数中

2 await后面可以是promise对象,也可以是数字 字符串

3 相比generator语义化更强

4 async返回的是一个promise对象

5 只要await语句后面Promise状态变成reject,那么整个async函数就会中断执行

async函数中抛出错误,影响后续代码:

1 使用try catch

try{}catch(err){}

2 promise本身就有catch,直接使用catch

demo:

async function demo(){
       await Promise.reject('出错了')
       console.log(await Promise.resolve('success'))
       console.log(await Promise.resolve('success1'))

   }
   demo();

结果:

出错了,后面的代码不会执行;

使用try catch

async function demo(){
       try{await Promise.reject('出错了')}catch(err){
            console.log(err);
       }
       console.log(await Promise.resolve('success'))
       console.log(await Promise.resolve('success1'))

   }
   demo();

下面的代码依然执行

使用promise的catch

async function demo(){
       await Promise.reject('出错了').catch(err=>{
        console.log(err);
       })
       console.log(await Promise.resolve('success'))
       console.log(await Promise.resolve('success1'))

   }
   demo();

结果同上

使用await的地方一般都是数据请求,都有出错的可能,都需要进行出错检测,建议都放在try catch中

async function demo(){
       try{
           await Promise.reject('出错了');
           await Promise.resolve('success')
           await Promise.resolve('success1')
        }catch(err){
            console.log(err);
       }
       
   }
   demo();

Set WeakSet 

新增的数据结构

Set数据结构,类似数组,但是里面不能有重复值

set的用法:

new Set([]);参数是一个数组 存储的是一个数组

数组去重

let arr=[1,2,3,4,5,1];
   let setArr=new Set(arr);
   console.log(setArr);

转成数组

Array.from(setArr)

let arr2=[...setArr]

set添加值 add

let setArr=new Set();

setArr.add('a');

setArr.add('b');

setArr.add('c');

删除一项元素

setArr.delete('a') 

判断set中是否包含某个值

setArr.has('a')//返回true false
setArr.size 属性,查看个数

setArr.clear()清除所有

可以使用for of进行遍历取值

setArr没有下标

 

WeakSet({}) 存储的是一个json,初始添加json不行,没有size和clear()需要用add添加  不太靠谱

总结:new Set() 不适用weakSet()

map

map:类似json,但是json的键(key)只能是字符串

map的key可以是任意类型

用法:

设置值set 

取值 get

删除元素 delete

是否包含某个元素has(key)

清空clear()

循环:

for of

demo:

   let map=new Map();
   let json={a:1,b:2};
   map.set('a','aaa');
   map.set(json,'aaa');
   map.set('aaa',json);
   console.log(map);
   console.log(map.get(json));

WeakMap() 官方文档说的是:key只能是对象

总结:

Set 里面是数组,不重复,没有key,没有get方法

Map 对json功能的增强,key可以是任意类型的值

 

Number

Number.isNaN()判断是否是NaN

Number.parseInt

Number.parseFloat

新增的方法

Number.isFinite()判断是否是数字

Number.isInteger() 判断数字是否是整数

安全整数:

-(2^53-1)~(2^53-1)

Number.isSafeInteger() 判断是否是安全整数

Number.MAX_SAFE_INTEGER  最大安全整数

Number._MIN_SAFE_INTEGER 最小安全整数

 Math

Math.abs()

Math.sqrt()

Math.sin()

Math.cos()

Math.trunc() 截取数据的整数部分

Math.sign(0)  0
Math.sign(-0)  -0
Math.sign(3)  1
Math.sign(-3)  -1
其他值 NaN

Math.cbert()  取一个值得立方值

Math.cbert(27)    3

判断一个数是 正数  负数  0 -0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

推荐阅读