关于前端:关于ES6

3次阅读

共计 9489 个字符,预计需要花费 24 分钟才能阅读完成。

ES6 环境:webpack3.0

ES6 申明变量

let:相当于 ES5 的 var
     但 var 没有块级作用域,而 let 有
     没有预解析,不存在变量晋升
     在代码块内,let 要先定义完再应用,只有 let 定义变量在之前应用都是报错(为暂时性死区(TDZ))同一个作用域里不能反复定义变量
     for 循环中,for 循环外面是父级作用域,循环外面又是一个
     举荐当前应用 let

const:定义常量(定义完变量后不能再次被赋值)但对于一些对象上本身的办法,能够利用其办法进行更改(如 array.push,...)有一特例:Object.freeze(能阻止扭转,即便是对象本身上的办法也不能被扭转)

ES6 解构赋值(实用)

用在数据交互 ajax 时十分有用

留神:左右两边,构造格局要保持一致
e.g. let [a,b,c]=[1,2,3] => a=1,b=2,c=3
     let json={
        name:'ckx',
        age:20,
        job:'wu'
     }
     let {name,age,job}=json => name='ckx',age=20,job='wu'
     
解构时能够给默认值:let [a,b,c='暂无']=[1,2]

解构可用于替换值:let a=1;
let b=2;
[a,b]=[b,a];

解构可用于接管函数返回的多个值:function a(){
    return{
        b:1,
        c:2
    }
}
let {b,c}=a() => b=1,c=2
     

ES6 字符串

字符串模板:`xxxxxxx`
长处:可随便换行
      `xxx${变量名}xxx`
e.g. let a=1;
     let b=2;
     let str=` 这里有 ${a}集体
              那里有 ${b}集体 `
              
字符串新增的一些办法:str.includes('xxx'):xxx 是否蕴含在 str 中(返回 true/false)str.indexOf('xxx'):返回 xxx 在 str 中的索引地位,找不到则返回 -1
str.startsWith('xxx'):str 是否以 xxx 结尾(返回 true/false)str.endsWith('xxx'):str 是否以 xxx 结尾(返回 true/false)str.repeat(n):str 反复 n 次
str.padStart(整个字符串长度(填充后的长度),填充的货色):str 往前填充
str.padEnd(整个字符串长度(填充后的长度),填充的货色):str 往后填充

ES6 函数

 设置默认参数:function({a='xx',b='xx'}){} 或 function(a,b){a=a || 'xx'; b=b || 'xx'}或 function({a,b}={}){}
 函数参数默认曾经定义了,不能再应用 let,const 申明
 
 扩大运算符 / 残余运算符:...
 开展数组:let arr=['a','b','c'];
          ...arr => 'a','b','c'
 合为数组:function(...a){...}
          show(1,2,3);
          此时的 a 为['1','2','3']
 当作残余参数:function(a,b,...c){console.log(a);
                   console.log(b);
                   console.log(c);
               }
              show(1,2,3,4,5);
              此时输入的 a 为 1,b 为 2,c 为 3,4,5
              
 箭头函数:()=> return 的货色
          ()=>{...}
 箭头函数的 this 指向定义函数所在的对象,而不是运行时所在的对象
 箭头函数没有 arguments,用 '...'
 箭头函数不能当构造函数
 

ES6 数组

ES5 里循环的办法:for
while
arr.forEach(fn(val,index,arr){}) / arr.forEach(fn,this 指向的对象)
arr.map(fn(val,index,arr){}) / arr.map(fn,this 指向的对象)(会返回一个新数组)arr.filter(fn(val,index,arr){}):过滤一些不合格的元素
arr.some(fn(val,index,arr){}):相似查找,数组外面某一个元素符合条件,返回 true
arr.every(fn(val,index,arr){}):数组外面所有元素符合条件,返回 true
arr.reduce(fn(prev,current,index,arr)):可用于求和 / 阶乘...(prev+current, 相似递归)(方向是从左往右)arr.reduceRight():相似 arr.reduce, 方向是从右往左
for(xx of xxx):xx 在 xxx 外面的循环(可配合 arr.keys()(数组下标),arr.entries()(数组的某一项)应用)数组的一些新增办法:扩大运算符 / 残余运算符:...(下面有介绍)Array.from(xxx):把类数组对象(xxx)转成数组
Array.of('xx','xxx','xx'):把一组值合并转为一个数组
arr.find(fn(val,index,arr){}):在 arr 中找到第一个合乎此条件的元素,若找不到则返回 undefined
arr.findIndex(fn(val,index,arr){}):在 arr 中找到合乎元素的下标地位,没找到则返回 -1
arr.fill('xxx',x,y):xxx 填充数组(范畴是从 x 到 y)arr.includes('xxx'):判断 arr 是否蕴含 xxx

ES6 对象

对象中的函数能够简写:let json={
                           a,
                           show(){...}(倡议不要应用箭头函数)}
 
Object.is():用来比拟两个值是否相等(肉眼看的相等就相等)新对象 =Object.assign(指标对象,source1,source2,...):用来合并对象(用处:复制一个对象 / 数组,合并参数)Object.keys(xxx):遍历对象的键值

Object.entries():遍历对象的每一项

Object.values():遍历对象的值

...:对象解构:let json={a:3,b:4};
              let json2={...json};  => json2={a:3,b:4}
              

ES6 Promise

作用:解决异步回调问题

let promise=new Promise(function(resolve,reject){  //resolve 为胜利调用,reject 为失败调用
            resolve('胜利');
            reject('失败');
})
promise.then(success 的 fn,fail 的 fn)
=> promise.then(res=>{... // 会输入 resolve 的内容},err=>{... // 会输入 reject 的内容})
promise.catch(err=>{...})  // 捕捉谬误  

连贯用法:new Promise(fn).then(res=>{}).catch(err=>{})

Promise.all([promise1,promise2,...]):把 promise 打包, 扔到一个数组里,打包完还是 promise 对象。必须确保所有 promise 对象都是 resolve 状态才可返回

Promise.race([p1,p2,...]):与 Promise.all 相似,但只有其中有一个 promise 对象是 resolve 状态即可返回

ES6 模块化

定义(导出)模块:export 'xxx'
引入模块的几种办法:import 'xxx'
                   import {xx,xx} from 'xxxx'
                   import {xxx as xx} from 'xxxx'
                   import * from 'xxxx'
                   
import:能够是相对路径,也能够是绝对路径
import 无论你引入多少次,只会导入一次
可改名:import * as a from 'xxx'
有申明晋升成果,import 会主动晋升到顶部
导出去模块内容,如果外面有定时器更改,里面也会改变,不像 Common 标准缓存
默认 import 语法不能写到 if 之类的语句中

另一种 import 的写法(返回的值是 Promise 对象):import('xxx').then(res=>{...})
              长处:按需加载
                    能够写在 if 之类的语句中
                    门路也能够动静
可与 Promise.all([])配合应用:Promise.all([import('xxxx1'),import('xxxx2')]).then(([m1,m2])=>{...});

与 async,await 配合:async function(){const mod1=await import('xxxx1');
    const mod2=await import('xxxx2');
    const [m1,m2]=await Promise.all([import('xxxx1'),import('xxxx2')]).then();}

export:可在外面改名:export{a as apple,b as banana}

ES6 类和继承

类:第一种形式:class xxx{constructor(){this.xxx='xx';}
    函数名(){},   // 命名函数
    [变量名](){},  // 表达式命名函数
}
第二种形式:const xxx=class{...}

class 外面的取值函数:get xxx(){}
           存值函数:set xxx(val){}
           
若想在 class 中间接应用类名调用外面办法,则在办法后面加上 static 

留神:class 没有申明晋升的性能

继承:extends,super()
class 子类名 extends 父类名{...}
e.g.1 class p{constructor(name){this.name=name;}
        showname(){return `${this.name}`
        }
     }
     
     class s extends p{constructor(name,skill){super(name);  // 继承时必须写(继承参数)this.skill=skill;
        }
        showname(){super.showname(); // 继承父级的办法
        }
        showskill(){return `${this.skill}`
        }
     }
     
e.g.2 拖拽
class Drag{constructor(id){this.odiv=document.getElementById(id);
        this.disX=0;
        this.disY=0;
        this.init();}
    init(){this.odiv.onmousedown=function(e){
            this.disX=e.clientX-this.odiv.offsetLeft;
            this.disY=e.clientY-this.odiv.offsetTop;
            
            document.onmousemove=this.Move.bind(this);
            document.onmouseup=this.Up.bind(this);
            return false;
        }.bind(this);
    }
    Move(e){
        this.odiv.style.left=e.clientX-this.disX+'px';
        this.odiv.style.top=e.clientY-this.disY+'px';
    }
    Up(){
        document.onmousemove=null;
        document.onmouseup=null;
    }
}

编写类 LimitDrag(限度范畴的拖拽,继承 Drag)class LimitDrag extends Drag{Move(e){super.Move(e);
        
        // 在这里只编写右边和顶部的范畴限度,其余两边可自行补充
        if(this.odiv.offsetLeft<=0){this.odiv.offsetLeft=0;}
        else if(this.odiv.offsetTop<=0){this.odiv.offsetTop=0;}
    }
}

ES6 Symbol 和 generator

Symbol 定义:let syml=Symbol('xxx');(以数据类型 symbol 定义一个惟一值)留神:Symbol 不能 new
      Symbol 返回是一个惟一值
      数据类型为 symbol(以前的六个根本类型:number,string,boolean,function,object,undefined)若 symbol 作为 key,用 for in 循环输不进去
      
generator 函数:生成器(解决异步,深度嵌套的问题)generator 定义:function * xxx(){}
e.g. function * welcome(){
           yield 'hello';
           yield 'world';
           return 'friend';
     }
     let w=welcome();
     // 手动调用
     w.next(); => hello done:false
     w.next(); => world done:false
     w.next(); => friend done:true(证实生成器中的内容已全副输入实现)// 主动调用
     for(let val of w){console.log(val); => hello world(但不会输入返回值)}
     // 进行解构赋值
     let [a,b,c]=welcome();
     console.log(a,b,c); => hello world undefined
     // 应用... 运算符
     let [a,...b]=welcome();
     console.log(a,b);
     或间接 console.log(...welcome());
     // 应用 Array.from
     console.log(Array.from(welcome()));
     
generator 还可配合 axios 应用:function * getdata(){
    let val=yield 'aa';
    yield axios.get('xxxxxx${val}');
}
let g=getdata();
let b=g.next().value;
g.next(b).value.then(res=>{...})

ES6 async 和 await

async function fn(){  // 示意此函数有异步工作 
    await xxx   // 示意前面的后果须要期待
}

async 特点:await 只能放到 async 函数中
相比 generator 语义化更强
await 前面能够是 promise 对象,也能够是数字,字符串,布尔
async 函数返回是一个 promise 对象
只有 await 语句前面 Promise 状态变成 reject,那么整个 async 函数都会中断执行 

解决 async 函数中抛出谬误,影响后续代码:第一种:try{}catch(e){
}
第二种:promise 自身的 catch

倡议:有 await 的中央,都放在 try...catch... 外面

ES6 Set 和 WeakSet

Set 是一个新的数据结构
Set 定义:let xxx = new Set() / new Set(['a','b'])

Set 的一些办法:xxx.add('xx'):往 xxx 增加一项 xx
xxx.delete('xx'):从 xxx 删除一项 xx
xxx.has('xx'):判断 xxx 中外面是否有 xx
xxx.size:得出 xxx 的值的个数
xxx.clear:清空 xxx 的所有值
可用 for...of... / xxx.forEach()循环 xxx 的值

可利用 Set 中的 key 值不能反复来实现数组去重:let arr=[1,2,2,3,4,5,5,5,8,2];
let set=[...new Set(arr)];
此时的 set 为[1,2,3,4,5,8]

Set 数据结构变成数组:[...set]

让 set 应用数组的 map,filter 办法:let set= new Set([1,2,3]);
set=new Set([...set].map(val=>val*2))
set=new Set([...set].filter(val=>val%2==0))

WeakSet:(不举荐应用)Set()外面最好放数组[],但能够间接利用 add 来把对象{}add 进去(间接放就不行)WeakSet()外面最好放对象{}
WeakSet 没有 size,clear 办法

ES6 Map 和 WeakMap

Map 定义:let map = new Map()

Map 的一些办法:map.set(key,value):设置一个值
map.get(key):获取一个值
map.delete(key):删除一个值
map.has(key):查看有没有那个值
map.clear():清空所有值
可用 for...of... / xxx.forEach()循环值

WeakMap:key 只能是对象

ES6 数字 (数值) 变动和无关 Math

数字(数值)变动:生成二进制(Binary):let a = 0b10100
生成八进制(Octal):let a = 0o456
生成十六进制(Hex):let a = 0hccd

ES6 新增的一些 Number 上的办法:Number.isFinite(xx):判断 xx 是不是数字
Number.isInteger(xx):判断 xx 是不是整数
Number.isSafeInteger(xx):判断 xx 是否为平安整数(平安整数的范畴:-(2^53-1) ~ 2^53-1,蕴含两端)Number.MAX_SAFE_INTEGER:显示最大平安整数
Number.MIN_SAFE_INTEGER:显示最小平安整数

 ES6 新增的一些 Math 上的办法:Math.trunc():截断(只保留整数局部(不会四舍五入))Math.sign():判断一个数是负数(返回 +1),正数(返回 -1),还是 0(返回 0),其余值(返回 NaN)Math.cbrt():计算一个数的开立方根
 

ES6 Proxy 和 Reflect

Proxy:代理(扩大对象的一些性能)作用:vue 中的拦挡性能,预警,上报,扩大性能,加强...

语法:new Proxy(target,handler);
     let obj=new Proxy(被代理的对象,对代理对象进行什么操作) 
     handle:(局部办法操作){set(target,prop,value){};  // 设置,拦挡
         get(target,prop){};  // 获取
         deleteProperty(target,prop){}; // 删除,拦挡
         has(target,prop){};  // 检测有没有某个货色
         apply(target,context,args){return Reflect.apply(...arguments)}; // 调用函数解决
         ...
     }
    
 e.g. let obj={name='ckx';}
       let newObj=new Proxy(obj,{get(target,property){console.log('你拜访了 ${property}属性')
                return target[property];
            }
       });
       console.log(newObj.name); => 'ckx'
       
 e.g.1 实现一个性能:DOM.xxx()(xxx 是什么就创立什么元素)const DOM = new Proxy({},{get(target,property){return function(attr={},...children){
                    // 创立元素
                    const el = document.createElement(property);
                    // 增加属性
                    for(let key of Object.keys(attr)){el.setAttribute(key,attr[key])
                    }
                    // 增加子元素
                    for(let child of children){if(typeof(child)=='string'){child=document.createTextNode(child);
                        }
                        el.appendChild(child);
                    }
                    return el;
                }
            }
       })
       let odiv=DOM.div({id:'div1',class='div2'},'我是 div1','和 div2')
       => <div id='div1' class='div2'>
            我是 div1
            和 div2
          </div>

Reflect: 反射(通过 Reflect 对象身上间接拿到语言外部的货色)Reflect.apply(调用的函数,this 指向,参数数组)
e.g. let res=Reflect.apply(Math.ceil,null,[9.8]);
     console.log(res); => 10

'assign' in Object => Reflect.has(Object,'assign');

 delete json.a => Reflect.deleteProperty(json,'a');

ES2018(ES9)新增的货色

命名捕捉:?< 名字 >
e.g. let str='2021-02-05';
     let reg=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
     let {year,month,day} = str.mathch(reg).groups;
     别离输入 year,month,day 为:2021,02,05
     
反向援用命名捕捉:\k< 名字 >
e.g. let reg=/^(?<world>hello)-\k<world>)$/;
     let str='a-a'; => false
     let str1='world-world'; => false
     let str2='hello-hello'; => true
     
     let reg=/^(?<world>hello)-\k<world>-\1)$/; => 匹配到的是:hello-hello-hello
     
替换:$< 名字 >
e.g. let str='2021-02-05'; 
     let reg=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
     str.replace(reg,'$<year>/$<month>/$<day>'); => 2021/02/05
另一种替换形式:str=str.replace(reg,(...args)=>{let {year,month,day} = args[args.length-1];
                    retrun `${year}/${month}/${day}`;
               })
               => 2021/02/05
 
dotAll 模式:s
在原来的正则中,'.' 示意匹配任何货色,除了 \r,\n(在 es6 里能够在正则表达式前面加上 s,以致都能匹配)e.g. let reg=/^\w+.\w+$/s;
     let str=hello\nworld; => true
     
标签函数:function xxx(args){console.log(args[0]); 
}
console.log(xxx`hello`);
输入为 hello

对于异步的几种解决方案

回调函数
事件监听
公布 / 订阅
Promise 对象

将 ES6 语法转换成 ES5 语法

1. nodesjs 中的 babel 模块(babel-preset-es2015 babel-cli)2. 新建文件.babelrc
3. 在新建的文件中编写:{
                        "presets":["es2015"],
                        "plugins":[]}
4. 利用 babel 转化本人写的 js 文件(含 ES6 语法)babel src/index.js(本人写的文件)-o dist/index.js(指标文件)文件夹的转换:babel src(本人文件所在的文件夹)-d dist(转化后的文件所在的文件夹)想要实时的编译:babel src/index.js(本人写的文件)-w -o dist/index.js(指标文件)babel src(本人文件所在的文件夹)-w -d dist(转化后的文件所在的文件夹)
正文完
 0