es6知识点总结

1.变量相关操作

let声明变量  const声明常量--声明变量,常量的扩展

  let不允许重复声明,var可以。

      const不允许重复声明,一旦声明不可修改,声明常量必须赋值,不能和var一样声明后再定义。

块级作用域--es6中定义的变量是块级作用域

     es5中的变量是函数级作用域。

     es6中凡是{}包裹的代码都是块级作用域,凡是在块级作用域中用let声明的的变量和const声明的的常量都有一个暂时性死区,作用域只能在{}内。

解构赋值--对赋值运算符的扩展

针对数组或者对象进行模式匹配,然后对其中的变量进行赋值  

/*
*1.赋值两边的结构必须完全一样
*2.赋值的右边必须是个标准对象
*3.赋值和解构必须在同一个语句中完成
*4.解构的只要不是对象或数组,都会先将其转化为对象,所以数字类型和布尔类型也换转化为对象
*/
let {a,b}={'a':1,'b':2};
console.log(a)
let {c,d}=[3,4];
console.log(c)
let [...d]='hello';
let {length}='hello';
// length:5
// d:['h', 'e', 'l', 'l', 'o']

2.函数

箭头函数

箭头函数与普通函数的区别

  • 箭头函数和普通函数的样式不同,箭头函数语法更加简洁、清晰,箭头函数是 =>定义函数,普通函数是 function定义函数。
  • Set 没有键只有值,可以认为 键和值 都一样
  • 箭头函数其实是没有 this 的,箭头函数中的 this 只取决包裹箭头函数的第一个普通函数的 this。
  • 箭头函数没有自己的arguments。在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。
  • call、apply、bind 并不会影响其 this 的指向。
  • 箭头函数的this指向上下文 ,而 普通函数的this并非指向上下文,需要时加入 bind(this)

表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super  

function add(x){
   return x+1;
}
function tip(y,fn){
   console.log(fn(y))
}

//es5
tip(1,add)

/*
*es6 *如果有且有一个参数,()可以不写 *如果有且仅有一个语句并且是return,{}也可以不写 */ tip(5,(x)=>{return x+1}) tip(5,x=>x+1)

修正this

箭头函数this为父作用域的this,不是调用时的this

<button id='btn'>按钮</button>
let btn=document.getElementById('btn');
btn.onclick=function(){
     //es5
     window.setTimeout(function(){
       console.log(this.id)     //undefined
     },2000)
    //es6
     window.setTimeout(()=>{
       console.log(this.id)     //'btn'
     },2000)
}

剩余参数--参数以...为前缀

允许将一个不定数量的参数表示为一个数组,它不仅可以收集,还能解构数据 

function tip(x,y,...z){
   console.log(z)
}
tip(1,2,3)    //[3]
tip(1,2,3,4,5)    //[3,4,5]
tip(1)     //[]

3.数组扩展方法

  • Array.of(): 将一组值转化为数组,返回一个新数组,并且不考虑参数的数量或类型。
  • copyWithin():把指定位置的成员复制到其他位置,返回原数组
  • find(): 返回第一个符合条件的值
  • findIndex(): 返回第一个符合条件的索引
  • keys():对键名的遍历,返回一个遍历器对象,可用for-of循环,
  • values():与 keys() 用法一样,不过是对 键值 的遍历
  • entries():与 keys() 用法一样,不过是对 键值对 的遍历
  • Array.from(): 从一个类似数组或可迭代对象中创建一个新的数组实例。
  • fill(): 使用制定的元素填充数组,返回原数组
  • includes():判断是否包含某一元素,返回布尔值,对 NaN 也有效,但不能进行定位

map方法--使用场景(假设后台返回的数据是一个数组对象,前端可以使用map返回一个新的数组)

当数组调用map方法时,即将原有的数组内容变换成新的数组内容

/*
*val表示元素值
*idx表示元素索引号 *arr表示遍历的数组 *函数必须要有return语句,没有return就没有新的数组
*/ let array=[30,40,50,60,70] let arr2=array.map(function(val,idx,arr){
return (val>=60?'及格':'不及格')
})
console.log(arr2)

forEach方法 

该方法用于数组中各元素的遍历,可以对遍历时的元素进行各项操作,但不会返回新的数组

/*
*val表示元素值
*idx表示元素索引号
*arr表示遍历的数组
*无返回值的函数,不会有新的数组产生
*/
<button>1</button><button>2</button><button>3</button>
let arr=[30,40,50,60,70] 
let btns=document.getElementByTagName('button');
let _btns=Array.from(btns) //将类数组转化为真正的数组--Array.from()
arr.forEach(val=>{console.log(val++)})
_btns.forEach(val=>{console.log(val)})

reduce方法

该方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值

/*
*initv-pro添加前初始值,若填,idx从0开始,若不填idx从1开始
*val表示元素值
*idx表示元素索引号
*arr表示遍历的数组
*函数必须要有return语句,没有return就没有新的数组
*/
let arr=[30,40,50,60,70]
let arr2=arr.map(function(pre,val,idx,arr){
   if(idx===arr.length-1){
        return (pre+val)/arr.length    //求平均值
   }else{
        return pre+val    //求和
   }
},10)
console.log(arr2)

filter方法

该方法用于数组中各元素的过滤,如果返回值为true,则作为新数组成员,否则被过滤

/*
*原数组不变,返回新的数组arr2
*val表示元素值
*idx表示元素索引号
*arr表示遍历的数组
*函数必须要有return语句,没有return就没有新的数组
*/
let arr=[30,null,undefined,'',0,40,50,60,70];
let arr0=arr.filter(val=>val)   //不为真的内容
let arr2=arr0.filter(val=>val%2===0)   //偶数
console.log(arr0)
console.log(arr2)

4.字符串对象扩展方法

  • Object.getPrototypeOf():返回对象的原型对象
  • Object.setPrototypeOf():设置对象的原型对象
  • proto:返回或设置对象的原型对象
  • Object.getOwnPropertyNames(): 返回对象自身非Symbol属性键组成的数组
  • Object.getOwnPropertySymbols(): 返回对象自身非Symbol属性键组成的数组
  • Reflect.ownKeys(): 返回对象自身全部属性键组成的数组
  • Object.is():判断两个对象是否相等,数组指向的地址不同,所以只要是数组比较,必定为 false
  • 遍历:for-in
  • Object.keys():返回属性名
  • Object.assign(): 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,返回目标对象,此时的目标对象也会改变

查询子类字符串的方法--es5里面使用indexOf()

string.includes(cStr,pos); //在字符串中查找
string.startsWith(cStr,pos);   //在字符串开始位置查找
string.endsWith(cStr,pos);     //在字符串结束位置查找
let str='this is a book';
//cStr:表示要查找的子字符串,pos:表示查询时的开始位置,不传默认为0 
string.includes(cStr,pos);     //在字符串中查找
str.includes('is')     //true
str.includes('is',6)     //false
str.includes('is',5)     //true

//cStr:表示要查找的子字符串,pos:表示查询时的开始位置,不传默认为0 
string.startsWith(cStr,pos);   //在字符串开始位置查找
str.startsWith('ab')     //false
str.startsWith('th')     //true
str.startsWith('th',2)     //false

//cStr:表示要查找的子字符串,pos:表示针对前第几个字符
string.endsWith(cStr,pos);     //在字符串结束位置查找
str.endsWith('ok')     //true
str.endsWith('th')     //false
str.endsWith('ok',2)     //false
str.endsWith('th',2)     //true   

字符串重复与补全的方法

string.repeat(count)      //重复显示指定的次数

string.padStart(lMax,aStr)   //字符串的补全--左侧

string.padEnd(lMax,aStr)   //字符串的补全--右侧

let str='hi,';
//
count表示需要重复的次数,若为小数,向下取整 string.repeat(count); //字符串重复显示指定的次数 str.repeat(2); //'hi,hi' str.repeat(3.7); //'hi,hi,hi,' //lMax:表示字符串最大的字符长度,aStr:表示需要补充的字符串内容 string.padStart(lMax,aStr); //给字符串进行补全操作--左侧
let str2='1';
str2.padStart(2,'0'); //'01'---小于10的时候字符串补全

str.padStart(6,'hi,'); //hi,hi, //lMax:表示字符串最大的字符长度,aStr:表示需要补充的字符串内容 string.padEnd(lMax,aStr); //给字符串进行补全操作--右侧 str.padEnd(6,'Tom'); //hi,Tom str.padEnd(8,'Tom'); //hi,TomTo

字符串模版

它是一个加强版的字符串,用反引号`进行包裹,

1.换行和绑定变量,

2.调用函数,

3.执行表达式运算,

4.直接输入字符串内容

<body>
    <ul>
        <li>您好</li>
    </ul>
    <script>
        let name='Mike';
        let x=8,y=9;
        function _name(item){
            return item;
        }
        let str=`<ul>
                    <li>${name},您好</li>
                    <li>${_name('Tom')},您好</li>
                    <li>结果:${'我是结果'}</li>
                    <li>结果:${x>y?x:y}</li>
                </ul>`;
        let div=document.createElement('div');
        div.innerHTML=str;
        document.body.appendChild(div);
    </script>
</body>

5.类型扩展

symbol类型

它是es6中扩展的原始类型,表示唯一的值,没有结构函数,不能使用new关键字定义,用于确保对象中属性名的唯一性

//symbol类型
let name=Symbol();
let person={};
{
    person[name]='a1';
    console.log(person[name])    //a1
}
{
    let name=Symbol();
    person[name]='b1';
    console.log(person[name])     //b1
}
console.log(person[name])     //a1

//string类型
let name='a';
let person2={};
{
    person2[name]='a1';
    console.log(person2[name])      //a1
}
{
    let name='a';
    person2[name]='b1';
    console.log(person2[name])    //b1
}
console.log(person2[name])     //b1

 Set集合类型---常常用于处理数组

Set 是ES6中新的数据结构,是类似数组,但成员的值是唯一的,没有重复的值

es5中对象类型:函数,数组,简单对象。

es6新增对象类型:Set类型,Map类型。

set集合类型:该类型的对象是一个集合,允许存储任何类型的值,但保存的值必须唯一,可以增加,删除和检测集合中是否包含指定属性名。

 1 let arr=[1,3,5];
 2 let arr2=[2,4,6,5];
 3 
 4 let a1=new Set();
 5 let a2=new Set(arr);
 6 let a3=new Set(arr2);
 7 
 8 a1.add("a":1,"b":2,"a":3);   // 确保唯一性,后面的替换前面的
 9 a1.add("abs");   
10 
11 a2.add([2,3,4,5,6]);   //add添加
12 a2.delete(3);             //delete删除
13 a2.has(5)                   //has查找。存在为true,不存在为false
14 
15 let c=new Set([...arr,...arr2])
16 let d=new Set([...arr].filter(x=>a3.has(x)))
17 
18 console.log(a1);
19 console.log(a2.size);      //获取a2的长度
20 console.log(c)       //数组除重
21 console.log(d)       //获取交集元素

Map数据类型---常常用于处理对象

Map 是ES6中新的数据结构,是类似对象,成员键是任何类型的值

es5中对象的key必须为字符串,Map数据类型对其扩展,集合的键名和值支持任意类型的数据

Map数据类型:用于定义一个有序列表,表现也是一个集合,拥有增加,删除和查询的功能

/*
*集合的键名和值支持任意类型的数据
*.set()方法存数据,.get()方法取数据,.delete()方法删除,.has()判断是否存在,.clear()清除整个集合
*/
let m=new Map();
let n={};

m.set('a',1).set('c',2);
m.set(n,1);

let a1=m.get('c');
let a2=m.get(n);
let f=m.has(n);     //查找,是否存在某key,存在为true
let d=m.delete('c')    //删除操作
m.clear();    //清除整个集合中所有的键值对

console.log(a1)     //2
console.log(a2)     //1
console.log(m.size)     //3
console.log(d)     //true

iterator迭代器

为各种不同类型的数据访问提供了一种同意的接口,只要部署了它,各种数据类型就可以直接遍历各个成员。

/*
*forEach语句里面不能用break跳出循环
*for in 效率不高,set,map定义的不能遍历
*for of存在内置遍历器,底层存在iterator迭代器的支持
*数组,类似数组,set集合对象,map集合对象 自动具有iterator迭代器
*/
let arr=[2,4,6,8];
let obj={
   length:2,
   0:1,
   1:2
}
//Array.from将类数组转化为数组
for(let item of Array.from(obj)){
    console.log(item)
}

for(let item of arr){
     if(item==4){
          break;
      }else{
          console.log(item)
     }
}

for(let i of s){
       console.log(i)      
}

6.处理异步嵌套调用

generator函数

为解决异步编程时的嵌套提供方案,函数返回一个生成器,根据yield语句生成每次挂起时的迭代器

/*
*function后面跟*为generator生成器函数
*只要生成器里面通过yield给他声明,挂起的内容,可直接通过for of来直接获取
*/

//定义
function * tip(){
   yield '1';
   yield '2';
   yield '3';
}
let gen=tip()

//取值过程
for(let i of gen){
   console.log(i)   //1 2 3 undefined
}

let [a,...b]=gen;
console.log(a,b)     //1 [2,3] 

console.log(...gen)    //1 2 3

//应用
function * ask(){
   let id=yield '1010';
   let work=yield id+'=>职业';
   let ad=yield=work+'=>广告';
}
let gen2=ask();
let id=gen2.next();
console.log(id.value);      //1010
let work=gen2.next(id.value);
console.log(work.value);    //1010=>职业
let ad=gen2.next(work.value);
console.log(ad.value)        //1010=>职业=>广告

promise对象

Promise 就是为了解决“回调地狱”问题的,它可以将异步操作的处理变得很优雅。

为解决异步编程时的嵌套提供方案,该对象接收两个函数为参数,并将每次执行结果作为参数传给函数

状态:

  • pending:[待定]初始状态
  • fulfilled:[实现]操作成功
  • rejected: [被否决]操作失败

Promise.all() 批量操作

  • Promise.all(arr)用于将多个promise实例,包装成一个新的Promise实例,返回的实例就是普通的promise
  • 它接收一个数组作为参数
  • 数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变
  • 当所有的子Promise都完成,该Promise完成,返回值是全部值得数组
  • 有任何一个失败,该Promise失败,返回值是第一个失败的子Promise结果

Promise.race()

  • race 与 all相似,只不过只要有一个执行完就会执行

Promise的问题

  • 一旦执行,无法中途取消,链式调用多个then中间不能随便跳出来
  • 错误无法在外部被捕捉到,只能在内部进行预判处理,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
  • Promise内部如何执行,监测起来很难,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
//基本定义
let a=5;
let p1=new Promise(function(resolve,reject){
    if(a>3){
        resolve(a)
    }else{
        reject('error')
    }
})
let p2=Promise.resolve('1010');

//使用
p1.then(function(s){
    console.log(s)
},function(e){
    console.log(e)
})

p2.then(function(d){
  console.log('id',d);
  //通过id获取到用户信息
  let user='用户信息';
  return d+'=>'+user;
}).then(function(d2){
  console.log('user2',d2);
  //通过用户信息获取到爱好
  let like='用户爱好'
  return d2+'=>'+like;
}).then(function(d3){
    console.log('like',d3);
    //通过用户信息获取到爱好
    let ad='用户广告'
    return d3+'=>'+ad;
}).then(function(d4){
    console.log('ad',d4)
})

async和await

async使用函数返回一个promise对象

await可以等待执行完成,使用异步请求变成同步效果

/*
*async返回一个promise对象
*若await后面为一个普通的字符串,与普通函数没区别,
*若await后面有promise对象并且里面有异步请求的功能 await等待执行完才执行下面语句
*若await作为一个返回值,则返回值的内容为异步请求成功之后的值传过来的内容
*/
function p(str) { 
    return new Promise((resolve)=>{
       setTimeout(()=>{
           console.log(str);
           resolve(str);
       },1000)
    })
 }
async function tip() {
    p('abc');
    console.log('ok')
}
async function tip2() {
    let aa=await p('abc');    //等待
    console.log(aa)
    console.log('ok')
 }

tip()       //'ok'   'abc'
tip2()      //'abc'  'abc'  'ok'

7.面向对象编程

es5里面没有类

类的定义

类的本质还是一个函数,class关键字是一个语法糖,使结构更清晰,形式上更似面向对象编程

/*
* 不允许定义2个及以上一样的类
*/
//声明一个类
class Person{
    //类里面包括属性和方法2个成员
    name='张三';    //原型属性
    static sex='男'    //静态属性,不需要实例话
    say(){            //原型方法,不能获取静态属性,其他属性均可获取
      console.log(this.name+','+this.age)      
    }
    static play(a,b){     //静态方法,只能获取静态属性,其他均不可获取
      console.log(a+b);
      console.log(this.age);   //undefined
      console.log(this.sex);   //
    }
    constructor(name,age){      //构造方法--实例话类对象的时候执行(new的时候))
        this.name=name;
        this.age=age;
        console.log(this.name,this.age)
    }
}
Person.prototype.age=18;    //公用属性
//定义一个类
let Person2=class{}

//调用类
let p1=new Person('王麻子',28);    
console.log(p1.name,p1.age,Person.sex);
p1.say();
Person.play(5,8)

类的封装和继承

封装使用类的成员更具统一性,继承可以扩展各类之间的联系,增加封装内容的复用性,可维护性。

/*
* 不允许定义2个及以上一样的类
* 如果继承的子类函数,有一个constructor,则必须调用super,并且如果是一些动态的属性,必须在super函数里面直接引用过来,则可以在子函数中直接使用父级属性
* 调用父类静态方法,可在子类中自己定义一个静态方法,通过super对象访问里面的静态方法
* super若在静态方法中表示整个类的对象,若在constructor中则表示实例话对象
*/
//声明一个类
class Person{
    //定义属性
    constructor(name,sex){ 
        this.name=name;
        this.sex=sex;
        this.age=18;
    }
    //方法
    say(){
        console.log(this.name+','+this.sex+','+this.age)
    }
    static sing(){
        console.log('唱歌中')
    }
}

//实例话一个类对象
let p1=new Person('王麻子','男');   
//调用方法
p1.say();
//声明一个类
class Hero extends Person{
    feature='勇敢';
    constructor(name,sex,act){
        super(name,sex,act);   //继承Person里面所有属性
        this.act=act;
    }
    play(){
        console.log(this.act)
    }
    static sing2(){   
        super.sing();
    }
}
//实例话Hero
let h1=new Hero('张三','男','利落');
h1.say();
h1.play();
Hero.sing2()    //Hero里面静态方法调用

模块化编程

es6中的模块化解决es5中不统一的问题,自动开启严格的结构模式,通股票import和export实现模块间的依赖关系

使用模块化的好处:

  • 解决命名冲突
  • 提供复用性
  • 提高代码可维护性

方案:

  • CommonJS:用于服务器(动态化依赖)
  • AMD:用于浏览器(动态化依赖,使用的很少)
  • CMD:用于浏览器(动态化依赖,使用的很少)
  • UMD:用于浏览器和服务器(动态化依赖)
  • ESM:用于浏览器和服务器(静态化依赖)

export 导出模块

  • 默认导出: export default Index
  • 单独导出: `export const name = 'domesy'
  • 按需导出(推荐): `export { name, value, id }'
  • 改名导出:export { name as newName }

import 导入模块

  • 默认导入(推荐): import Index from './Index'
  • 整体导入: import * as Index from './Index'
  • 按需导入(推荐): import { name, value, id } from './Index'
  • 改名导入: import { name as newName } from './Index'
  • 自执导入: import './Index'
  • 符合导入(推荐): import Index, { name, value, id } from './Index'

复合模式

export命令import命令结合在一起写成一行,变量实质没有被导入当前模块,相当于对外转发接口,导致当前模块无法直接使用其导入变量,适用于 全部子模块导出

  • 默认导入导出: `export { default } from './Index'
  • 整体导入导出: `export * from './Index'
  • 按需导入导出: `export { name, value, id } from './Index'
  • 默认改具名导入导出: `export { default as name } from './Index'
//common.html
let name='张三';
let age=18;
const PI=3.1415926;
function add(a,b){
    return a+b;
}
class Person{
    constructor(name,sex){
        this.name=name;
        this.sex=sex;
    }
    say(){
        console.log(this.name+','+this.sex)
    }
}
export {
    name as n,
    age,
    PI,
    add,
    Person
};

let num1=100;
let num2=200;
export default {num1,num2};
//mod.html <Script type='module'> //方法一引用 import num1,num2,{n,age as a,PI,add,Person} from './common.html' console.log(n,a,PI); console.log(add(5,8)); let p1=new Person('张三','女'); p1.say(); console.log(num1,num2) //方法二引用 import('./common.html').then(d=>{ console.log(d.n); let p2=new d.Person('王麻子','女'); p2.say(); }) </Script>
posted @ 2020-04-27 19:19  诉诉飞飞  阅读(212)  评论(0编辑  收藏  举报