前言
路漫漫其修远兮,吾之上下而求索
es6的探索之路
Decorator
修饰器是一函数,修改类的行为。扩展类的功能,只能在类中使用
基本使用
{
let readonly=function(target,name,descriptor){
descriptor.writable=false;
return descriptor
};
class Test{
@readonly
time(){
return '2017-03-11'
}
}
let test=new Test();
// test.time=function(){
// console.log('reset time');
// };
console.log(test.time());
}
{
let typename=function(target,name,descriptor){
target.myname='hello';
}
@typename
class Test{
}
console.log('类修饰符',Test.myname);
// 第三方库修饰器的js库:core-decorators; npm install core-decorators
}
使用场景
// 埋点日志 将埋点系统抽离出来,变成一个可复用的模块,比如埋点的接口改变,通信方式改变,只需要改动接口相关的代码,广告的类几乎不需要改变,保证代码的复用性,维护性和简洁性也会增加
{
let log=(type)=>{
return function(target,name,descriptor){
let src_method=descriptor.value;
descriptor.value=(...arg)=>{
src_method.apply(target,arg);
console.info(`log ${type}`);
}
}
}
class AD{
@log('show')
show(){
console.info('ad is show')
}
@log('click')
click(){
console.info('ad is click');
}
}
let ad=new AD();
ad.show();
ad.click();
}
Generator
基本使用
{
// genertaor基本定义
let tell=function* (){
yield 'a';
yield 'b';
return 'c'
};
let k=tell();
console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());
}
{
let obj={};
obj[Symbol.iterator]=function* (){
yield 1;
yield 2;
yield 3;
}
for(let value of obj){
console.log('value',value);
}
}
{
let state=function* (){
while(1){
yield 'A';
yield 'B';
yield 'C';
}
}
let status=state();
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
}
应用场景
抽奖
let txt = document.createElement('p');
txt.innerHTML = '当前抽奖剩余<span id = "count">5</span>次'
document.body.appendChild(txt);
let btn = document.createElement('button');
btn.id='start';
btn.textContent ='抽奖';
document.body.appendChild(btn);
//抽奖次数变化
function draw(num){
let count = document.getElementById('count')
count.innerHTML = `${num}`
console.log(`剩余${num}次`)
}
//判断当前是否继续抽奖
function* lottery(num){
while(num > 0){
num--;
yield draw(num)
}
}
let star = lottery(5) //这里次数由服务端提供接口
document.getElementById('start').addEventListener('click', function(){
star.next()
}, false)
长轮询
let ajax = function* () {
yield new Promise((resolve,reject)=>{
//这里是后端的请求接口
setTimeout(()=>{
resolve({code:1})
})
})
}
let pull = function() {
let generator = ajax();
let step = generator.next();
step.value.then(function(txt){
if(txt.code!=0){
setTimeout(()=>{
console.log('等待更新')
// pull()
},2000)
}else {
console.log(txt)
}
})
}
pull()
set-map数据结构篇(优先考虑set map,放弃array,obj)
set的基本用法
//关键 add添加值 size长度
let list = new Set();
list.add(5);
list.add(7);
console.log('size',list.size);//2
//也可以add数组
let arr = [1,2,3,4,5];
let list = new Set(arr);
console.log('size',list.size);//5
console.log(list);//Set(5) {1, 2, 3, 4, 5}
//set有去重是特性,前提是===
let list = new Set();
list.add(1);
list.add(2);
list.add(1);
console.log('list',list);//list Set(2) {1, 2}
let arr=[1,2,3,1,'2'];
let list2=new Set(arr);
console.log('unique',list2);//unique Set(4) {1, 2, 3, "2"}
//has是否有某个值,delete删除,clear清空
let arr=['add','delete','clear','has'];
let list=new Set(arr);
console.log('has',list.has('add'));//true
console.log('delete',list.delete('add'),list);//delete true Set(3) {"delete", "clear", "has"}
list.clear();
console.log('list',list);//list Set(0) {}
应用场景
//数组去重
let arr=['add','delete','clear','has','clear','has'];
let arr2 = []
let list=new Set(arr);
for(let [key,value] of list.entries()){
arr2.push(value)
}
console.log(arr2)//["add", "delete", "clear", "has"]
WeakSet(1.只能是对象不能是数值,字符串,布尔值等,2.弱引用,不会检测这个对象有没有在其他地方用过,不会跟垃圾回收机制挂钩上)
WeakSet基本使用
let weakList=new WeakSet();
let arg={};
weakList.add(arg);
// weakList.add(2);//报错
console.log('weakList',weakList);//weakList WeakSet {{…}}
Map的基本用法
// 可以用数组做下标
let map = new Map();
let arr=['123'];
map.set(arr,456);
console.log('map',map,map.get(arr));//map Map(1) {Array(1) => 456} 456
//map的size、delete和clear差不多
let map = new Map([['a',123],['b',456]]);
console.log('map args',map);
console.log('size',map.size);
console.log('delete',map.delete('a'),map);
console.log('clear',map.clear(),map);
WeakMap的基本用法
//set 设置值,get 获取值
let weakmap=new WeakMap();
let o={};
weakmap.set(o,123);
console.log(weakmap.get(o));//123
promise篇
promise其实就是一个对象,用来传递异步操作的消息,用promise的好处是代码简洁优雅,方便后期的维护,避免传统回调方式的处理的缺点,我们不知道回调的先后顺序,并且太多回调会让我们掉进回调地狱。
基本使用
传统的方式
let ajax=function(callback){
console.log('执行');
setTimeout(function () {
callback&&callback.call()
}, 1000);
};
ajax(function(){
console.log('timeout1');
})
promise方式
将异步的代码通过return new promise的执行,在异步操作后执行的代码写在then的function里边,第一个function代表resolve,第二个function代表reject
let ajax=function(){
console.log('执行3');
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 1000);
})
};
ajax()
.then(function(){
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 2000);
});
})
.then(function(){
console.log('timeout3');
})
应用场景
场景1:连续三个异步操作按顺序执行(我们在开发过程中一定遇到过,第二个接口所请求的参数是第一个接口返回的值吧,有时候甚至第三,第四,第n个接口的参数是根据前面的返回的字段请求,像写一个省市县的三级联动的需求等)
let ajax=function(){
console.log('执行3');
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 1000);
})
};
ajax()
.then(function(){
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 2000);
});
})
.then(function(){
console.log('timeout3');
})
场景2:中间某一步出错了,怎么捕获错误
// 关键:throw new Error和catch
let ajax=function(num){
console.log('执行4');
return new Promise(function(resolve,reject){
if(num>5){
resolve()
}else{
throw new Error('出错了')
}
})
}
ajax(6).then(function(){
console.log('log',6);
}).catch(function(err){
console.log('catch',err);
});
ajax(3).then(function(){
console.log('log',3);
}).catch(function(err){
console.log('catch',err);
});
场景3:所有图片加载完再添加到页面
//关键 Promise.all
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(imgs){
imgs.forEach(function(img){
document.body.appendChild(img);
})
}
Promise.all([
loadImg('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2714783560,2670973992&fm=26&gp=0.jpg'),
loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),
loadImg('https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=4171635295,1860398794&fm=26&gp=0.jpg')
]).then(showImgs)
场景4:有一个图片加载完就添加到页面(常用的场景还有倒计时,异步操作和定时器放到一起,如果定时器先触发,认为超时,告知用户)
// 关键 Promise.race
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(img){
let p=document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
Promise.race([
loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),
loadImg('http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png')
]).then(showImgs)
Module模块化
基本使用
export导出
/*导出的文件testExport.js*/
/*第一种 分别导出*/
export let A=123;
export function test(){
console.log('test');
}
export class Hello{
test(){
console.log('class');
}
}
/*第二种 以一个对象的形式导出*/
let A=123;
let test=function(){
console.log('test');
}
class Hello{
test(){
console.log('class');
}
}
export default {
A,
test,
Hello
}
import引入
/*导入的文件testImport.js*/
// 第一种,必须和export的名称完全一致
import { A,test,Hello} from testExport.js
// 第二种,以对象形式import
import dataExport from testExport.js
let a = dataExport.A
console.log(a);//123
推荐大家使用第二种方法啦,可以根据自己的需要起不同的名字取值,而且导出的时候也可以少写一些代码