解构赋值
- 实现变量替换
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*2
console.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;}
}
// 拦挡 delete
deleteProperty(target,key){if(key.indexof('_')>-1){delete target[key];
return true
}
else{return target[key]
}
}
// 拦挡 Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
ownKeys(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 false
delete monitor.time
console.log('delete',monitor)// 删除失败
delete monitor._r
console.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 等局部还须要独自强化学习。
一入前端深似海,愿不负好年华!