解构赋值
- 实现变量替换
let a =1;let b=2[a,b]=[b,a]console.log(a,b)//2,1
- 默认值赋值
[a,b,c=3]=[1,2]console.log(a,b,c)//1,2,3
- 间接获取函数返回值
function fc(){ return [1,2]}let a,b;[a,b]=fc()console.log(a,b)//1,2
- 对象的嵌套解构赋值
let metadata={title:'currentTitle',test:[{title:"deepTitle",desc:'description'}]}let {title:titleone,test:[{title:titlescond}]}=metadata;console.log(titleone,titlescond)//currentTitle,deepTitle
字符串拓展
unicode编码大于0XFFFF的,须要用codePoint配套办法去操作
String.includes
String.startsWith
String.endsWith
模板字符串:
let name="list"let info="hello world"let m=`i am ${name}',${info}`console.log(m)// i am list,hello world
padStart:前补白1.string.padStart(length,'char')//基于以后字符传补充char,返回长度为length
padEnd:后补白//基于以后字符传补充char,返回长度为length
标签模板:
let user={
name:"list",
info:"hello world"
};
console.log(abci am ${user.name},$(user.info)
)
function abc(s,v1,v2){
return s+v1+v2
}
数组的扩大
let arr =Array.of(3,4,7,9,11)console.log('arr=',arr)}//数组的生成
{ Array.from//把伪数组转化成数组let p=document.querySelectorAll("p")let pArr=Array.from(p)pArr.forEach{function(item){console.log(item.textContent)}}}Array from 还能够实现相似map的性能console.log(Array.from([1,3,5],function(item){return item*2}))
arrray.keys()遍历下标
array.values()遍历值
array.entries()一起来
{console.log([1,2,3,4,5].copyWithin(0,3,4))//[4,2,3,4,5]/*param1:被替换的下标param2:替换的起始下标,param3:替换的完结下标(左闭右开)当替换的长度加上起始点下标+1大于数组长度的时候,多进去的不会循环替换console.log([1,2,3,4,5].copyWithin(3,1,4))//[1,2,3,2,3]*/}[1,2,3,4,5,6].find(function(item){return item >3})//4,只会返回第一个合乎的值[1,2,3,4,5,6].findIndex(function(item){return item >3})//3,只会返回一个合乎的下标[1,2,NaN].includes(1)//true[1,2,NaN].includes(NaN)//true
函数扩大
- 函数默认值
function test(x,y=10){console.log('默认值',x,y)}test("hello")//hello 10
*默认值前面不能没有默认值的变量
function test3(x,y=10,z)//错的
- res参数
function test3(...args){for(let v of args){console.log("rest",v)}}test3(1,2,3,4,'a')
- 扩大运算符
{console.log(...[1,2,4])//1 2 4}
- 箭头函数
残缺的箭头函数
()=>{return XXXX}
只有return的时候可省略不写
let arrow =v=>v*2console.log('arrow',arrow(3))//6
this绑定问题(不晓得的JS读书笔记中有)
- 尾调用
{function tail(x){ console.log('tail',x)}function fx(x){ return tail(x)}}fx(123)//123
对象扩大
- 简洁表示法
{let o=1;let k=2;let es5={ o:o, k:k}}等价于let es6={ o,k}let es5_function={ hello:function(){ console.log('hello')}let es6_function={ hello(){ console.log('hello')}}}
- 属性表达式
let a ='b'let es6_obj={ a:'c'};let es6_obj={ [a]:'c'}console.log(es6_obj)//{b:'c'}
- 新增API
Object.is('数组',Object.is([],[]),[]===[])//true is办法(相当于===)Object.assign({a:a},{b:'b'})//{a:'a',b:'b'};//浅拷贝let test ={k:123,o:456};for(let [key,value] of Object.entries(test)){ console.log([key,value])}//["k",123] ["o",123] 对象的遍历,和数组相似、*Object.values和数组相似,babel反对不敌对*//扩大运算符 *babel反对也不敌对*let {a,b,...c}={a:'test',b:'kill',c:'ddd',d:'ccc'}c={c:'ddd',d:'ccc'}
Symbol数据类型
- 提供一个举世无双的值
let a1=Symbol();let a2=Symbol();console.log(a1===a2)false//永远不可能相等let a3=Symbol.for('a3')let a4=Symbol.for('a3')//获取Symbol的办法console.log(a3===a4)true理论应用let a1=Symbol.for('abc')let obj={[a1]:'123','abc':345,'c':456}for (let [key,value] of Object.entries(obj)){ console.log('let of ',key value)}//abc 345 c 456 拿不到以Symbol为键值的元素Object.getOwnPropertySymbols(obj).forEach(function(item){ console.log(obj[item])//123拿到Symbol的键})Reflect.ownkeys(obj).forEach(function(item){ console.log(ownkeys,obj[item])//该办法能够拿到所有的值})
数据结构
- Set
Set汇合中的元素不能反复
Set中的长度用size示意let list = new Set()list.add(5)list.add(7)console.log("size",list.size)//2 能够用Set去重let list = new Set()list.add(1)list.add(2)list.add(1)console.log("list ",list )//1,2
- weakSet
weakSet:只能放对象,弱援用,不能遍历,没有size属性,没有clear属性
- Map
key能够是任意类型
let map =new Map()
let arr=['123']
map.set(arr,456)
console.log('map',map,map.get(arr))// {["1230"=>456]} 456
{
let map= new Map(['a',123],['b',456]);
console.log('map arg')//{'a'=>123,'b'=>456}
//获取长度 size
//获取值 get
//删除 delete
//清空clear
}
- weakMap
关系和Set和WeakSet之间的关系统一
Set Map Array的增删改查
- 增
map.set("t",1)set.add({"t":1})array.push({t:1})
- 删
map.delete('t')set.forEach(item=>item.t?set.delete(item):' ')let index=array.findIndex(item=>{item.t})array.splice(index,1)
- 改
map.set('t',2)set.forEach(item=>item.t?item.t=2:'')array.forEach(item=>item.t?item.t=2:' ')
- 查
let map_exist=map.has('t')let set_exist=set.has({t:1})let array_exist=array.find(item=>item.t)
Proxy和Reflect
Proxy包装对象
{let obj ={time:'2017-03-11',name:'net',_r:123}let monitor =new Proxy(obj,{//读取 get(tartget,key){ return target[key].replace('2017',2018)}//设置 set(target,key,value){ if(key==='name'){ return target[key]=value}else{ return tartget[key]}}//拦挡key in obj的操作 has(target,key){ if(key==='name'){ return target[key]}else{ return false;} }//拦挡deletedeleteProperty(target,key){ if(key.indexof('_')>-1){ delete target[key]; return true}else{ return target[key] }}//拦挡Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNamesownKeys(target){ return Object.keys(target).filter(item=>item!='time') } })console.log('get',monitor.time)//2018-03-11 在Proxy中拿属性monitor.time=2018//不会失效monitor.name='xixixi'//失效console.log('has','name' in monitor,'time' in monitor )//true falsedelete monitor.timeconsole.log('delete',monitor)//删除失败delete monitor._rconsole.log('delete',monitor)删除胜利console.log('ownKeys',Object.keys(monitor));//便当中不会有time}Proxy相当于一个拦截器,在用户对某对象实际操作之前对操作进行批改
Reflect包装对象
{let obj={ time:'2017-03-11', name:'net', _r:123} console.log('Reflect get',Reflect.get(obj,'time'));//和Proxy所有办法相似}
应用Proxy和Reflec做一个验证器
function validator(target, validator) { return new Proxy(target, { _validator: validator, set(target, key, value, proxy) { if (taget.hasOwnProperty(key)) { let va = this._validator[key]; if (!!va(value)) { return Reflect.set(target, key, value, proxy) } else { throw Error(`不能设置${key}到${value}`) } } else { throw Error(`${key} 不存在`) } } })}const personvalidators = { name(val) { return typeof val === 'string' }, age(val) { return typeof val === 'number' && val > 18 }}class Person { constructor(name, age) { this.name = name this.age = age return validator(this, personvalidators) }}const person = new Person('lilei', 30)console.log(person)//Proxy{name:"lilei",age:"30"}person.name=48;//不能设置name为48
ES6中的类与对象
{ class Parent { constructor(name = "heiheihie") { this.name = name } } class child extends Parent { constructor(name = 'child') { super(name) } }}
Promise
- 传统回调
//异步操作 毛病: 多层次回调代码构造会特地艰涩难懂{ //根本定义 let ajax = function (callback) { console.log("执行") setTimeout(() => { callback && callback() }, 1000); } ajax(function () { console.log("timeout1") }) //执行 timeout1}
- promises根本用法
{ let ajax = function () { console.log("执行2") return new Promise(function (resolve, reject) { if (true) { setTimeout(() => { resolve() }, 1000) } else { reject() } }) } ajax().then(function () { console.log('promise', 'resolve') }, function () { console.log("promise", "reject") })}
- 基于Promise的屡次回调调用
{ let ajax = function () { console.log("执行3") return new Promise(function (resolve, reject) { setTimeout(() => { console.log("第一个resolve") resolve() }, 1000) }) } ajax() .then( function () { return new Promise(function (resolve, reject) { setTimeout(() => { console.log("第二个resolve") resolve() }, 2000) }) }) .then(function () { console.log('timeout3') })}
- 异样捕捉
{ let ajax = function (num) { console.log("执行4") return new Promise(function (resolve, reject) { if (num > 5) { resolve() } else { throw new Error("出错了") } }) } ajax(10).then(function () { console.log("log", 10) }).catch(function (err) { console.log('catch', err) }) ajax(3).then(function () { console.log("log", 3) }).catch(function (err) { console.log('catch', err) })}
Promise中的all和race办法
**当all办法中的所有实例返回的都是resolve的时候,才会执行then办法
以上面代码为例子,当所有的图片都加载实现之后,才会进行Dom操作**
{ function loadImg(src) { return new Promise((resolve, reject) => { let img = document.createElement('img') img.src = src img.onload = function () { resolve() } img.onerror = function (err) { reject(err) } }) } function showImgs() { imgs.forEach(function (img) { document.body.appendChild(img) }) } Promise.all([ loadImg('xxxxxxxxxxxxxxxxxxxxxxxxxxx'), loadImg('xxxxxxxxxxxxxxxxxxxxxxxxxxx'), loadImg('xxxxxxxxxxxxxxxxxxxxxxxxxxx') ]).then(showImgs)}
当race办法中的有一个实例返回resolve的时候,就会执行then办法
Iterator和循环
当应用for...of循环遍历某种数据结构时,该循环会主动去寻找 Iterator 接口。
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只有具备Symbol.iterator属性,就能够认为是“可遍历的”(iterable)。
ES6 的有些数据结构原生具备 Iterator 接口(比方数组),即不必任何解决,就能够被for...of循环遍历。起因在于,这些数据结构原生部署了Symbol.iterator属性(详见下文),另外一些数据结构没有(比方对象)。但凡部署了Symbol.iterator属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。(整段摘自ES6入门)
天生自带Iterator接口的数据结构有:
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象
let arr = ['a', 'b', 'c'];let iter = arr[Symbol.iterator]();iter.next() // { value: 'a', done: false }iter.next() // { value: 'b', done: false }iter.next() // { value: 'c', done: false }iter.next() // { value: undefined, done: true }
为对象增加遍历器接口
let obj = { data: [ 'hello', 'world' ], [Symbol.iterator]() { const self = this; let index = 0; return { next() { if (index < self.data.length) { return { value: self.data[index++], done: false }; } else { return { value: undefined, done: true }; } } }; }};
Generator
//Generator的作用
{ let tell = function* () { yield 'a'; yield 'b'; return 'c' } /*//async和await等价*和yield 是它们的语法糖let tell =async function() { await 'a'; await 'b'; await 'c' }*/ let k = tell(); console.log(k.next())}//能够了解为Generator能够把一个函数拆开异步执行
通过创立Generator函数的形式创建对象的遍历接口iterator
{ let obj = {} obj[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; for (let value of obj) { console.log('value', value) } }}
//利用Generator实现抽奖逻辑,缩小不平安的全局变量
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title></head><body> <script> let draw = function (count) { console.log(`以后残余${count}次`) } let residue = function* (count) { while (count > 0) { count--; yield draw(count) } } let start = residue(5) let btn = document.createElement('button') btn.id = 'start' btn.textContent = "抽奖" document.body.appendChild(btn) document.getElementById('start').addEventListener('click', function () { start.next() }, false) </script></body></html>
应用Generator实现轮询性能
let ajax = function* () { yield new Promise(function (resolve, reject) { setTimeout(() => { resolve({ code: 1 }) }, 200); }) } let pull = function () { let generator = ajax(); let step = generator.next() step.value.then(function (d) { if (d.code != 0) { setTimeout(() => { console.log('wait') pull() }, 1000) } else { console.log(d) } }) } pull()
Decorator
defination:一个函数,用来批改类的行为
//根本用法
{ let readonly=function(target,name,descriptor){ descriptor.writable=false return descriptor }; class Test{ @readonly time(){ return '2019-03-18' } } let test=new Test(); console.log(test.time())// "2019-03-18" test.time=function(){ console.log('reset time') } console.log(test.time())//cannot assign to read only property 'time' of object '#Test'}
{ let typename=function(target,name,descriptor){ target.myname='hello' }; @typename class Test{ } console.log('类修饰符',Test.myname)//类修饰符 hello}
第三方润饰器的库 core-decorators
https://www.npmjs.com/package...
模块化
//已相熟
本篇文章基于慕课网ES6零根底教学示例(Iterator局部摘自ES6入门)
https://coding.imooc.com/clas...
手动敲代码加强以便本人的记忆
视频对于ES6的语法用独自的例子做了简略的介绍和理论应用的例子
对于Promise,Decorator,Generator等局部还须要独自强化学习。
一入前端深似海,愿不负好年华!