欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6基础

程序员文章站 2022-05-03 17:38:17
...

资料来源 imooc

推荐es6入门教程 ECMAScript 6 入门-ruanyifeng

lesson1-let,const

ES6基础
声明变量,块级作用域;

注意:

const a = 1;a=2;//error

const k={a:1};k.b=2;//是对的,因为他的意思的声明的引用不可变;

function test(){
  // for(let i=1;i<3;i++){
  //   console.log(i);
  // }
  // console.log(i);
  let a = 1;
  // let a = 2;
}

function last(){
  const PI=3.1415926;
  const k={
    a:1
  }
  k.b=3;
  console.log(PI,k);
}


// test();
last();

lesson2-解构赋值(与…结合)

ES6基础

// 解构赋值
// 接收数组
{
  let a,b,rest;
  [a,b]=[1,2];
  console.log(a,b);
}
// 与...拓展运算符结合
{
  let a,b,rest;
  [a,b,...rest]=[1,2,3,4,5,6];
  console.log(a,b,rest);
}
// 接收对象
{
  let a,b;
  ({a,b}={a:1,b:2})
  console.log(a,b);
}

// 添加默认值,防止左右不匹配
{
  let a,b,c,rest;
  [a,b,c=3]=[1,2];
  console.log(a,b,c);
}

// 变量交换
{
  let a=1;
  let b=2;
  [a,b]=[b,a];
  console.log(a,b);
}
// 接收函数返回数组
{
  function f(){
    return [1,2]
  }
  let a,b;
  [a,b]=f();
  console.log(a,b);
}

// 只接受1和4
{
  function f(){
    return [1,2,3,4,5]
  }
  let a,b,c;
  [a,,,b]=f();
  console.log(a,b);
}
// 与...拓展运算符结合
{
  function f(){
    return [1,2,3,4,5]
  }
  let a,b,c;
  [a,,...b]=f();
  console.log(a,b);
}

{
  let o={p:42,q:true};
  let {p,q}=o;
  console.log(p,q);
}

{
  let {a=10,b=5}={a:3};
  console.log(a,b);
}

{
  let metaData={
    title:'abc',
    test:[{
      title:'test',
      desc:'description'
    }]
  }
  let {title:esTitle,test:[{title:cnTitle}]}=metaData;
  console.log(esTitle,cnTitle);
}

lesson3-正则拓展

ES6基础

{
    // #构造函数#
    let regex = new RegExp('xyz', 'i'); //第一个参数是字符串,第二个是修饰符
    let regex2 = new RegExp(/xyz/i); //第一个参数是正则表达式,不接受第二个参数,否则会报错
    console.log(regex.test('xyz123'), regex2.test('xyz123'));
    console.log(regex.test('xyZ123'), regex2.test('xyZ123'));

    let regex3 = new RegExp(/abc/ig, 'i');
    console.log(regex3.flags); //原有正则对象的修饰符是ig,它会被第二个参数i覆盖

}

// 字符串对象的4个使用正则表达式的方法: match(),replace(),search(),split()这四个方法全部调用RegExp的实例的方法。

{
    let regex = new RegExp('xyz', 'ig');
    console.log(regex.test('xyz0XYZ1xyz2'), regex.exec('xyz0XYZ1xyz2'));
}

// y和g修饰符区别 开启粘连模式
{
    // y修饰符
    let s = 'bbbb_bbb_bb_b';
    var a1 = /b+/g;
    var a2 = /b+/y;

    console.log(a1.exec(s), a2.exec(s)); // ["bbbb"],["bbbb"]
    console.log(a1.exec(s), a2.exec(s)); // ["bbb"],null

    console.log(a1.sticky, a2.sticky); //表示是否开启了粘连模式
}

// u修饰符 大于0xFFFF(一个字节)的Unicode字符,`.`匹配任何字符,但是大于一个字节要加`u`

{
    console.log('u修饰符',/^\uD83D/.test('\uD83D\uDC2A')); // true 这里当成两个字符
    console.log('u修饰符',/^\uD83D/u.test('\uD83D\uDC2A')); // false 这里当成一个字符
    // 大括号表示Unicode字符,只有加上u才能识别
    console.log(/\u{61}/.test('a')); // false
    console.log(/\u{61}/u.test('a')); // true
    console.log(/\u{20BB7}/u.test('????')); // true
    // 点(.)字符不能识别码点大于0xFFFF(两个字节)的Unicode字符,必须加上u修饰符。
    let s = '????';
    console.log('大于0xFFFF的Unicode字符',/^.$/.test(s)); // false
    console.log('使用u字符',/^.$/u.test(s)); // true

    // 使用u修饰符后,所有量词都会正确识别大于码点大于0xFFFF的Unicode字符。
    console.log('量词',/a{2}/.test('aa')); // true
    console.log('量词',/a{2}/u.test('aa')); // true
    console.log('量词',/????{2}/.test('????????')); // false
    console.log('量词',/????{2}/u.test('????????')); // true
}

{
    // #正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是行终止符(line terminator character)除外
    // U+000A 换行符(\n)
    // U+000D 回车符(\r)
    // U+2028 行分隔符(line separator)
    // U+2029 段分隔符(paragraph separator)
    // 只是一个提案目前还不支持
    // let reg=/test.go/s;
    // console.log(reg.test('test\ngo'));
    // console.log(reg.test('test\ngo'));
    console.log('s变通方法',/foo.bar/.test('foo\nbar'));
    console.log('s变通方法',/foo[^]bar/.test('foo\nbar'));
}

lesson4-字符串拓展

ES6基础
babel-polyfill兼容

// 大于两个字节 0xFFFFF
{
  console.log('a',`\u0061`); //a a
  console.log('s',`\u20BB7`);//s ₻7

  console.log('s',`\u{20BB7}`);//s ????

}
// 下标取字节
{
  let s='????a';
  console.log('length',s.length);
  console.log('0',s.charAt(0));
  console.log('1',s.charAt(1));
  console.log('at0',s.charCodeAt(0));
  console.log('at1',s.charCodeAt(1));

  let s1='????a';
  console.log('length',s1.length); //3
  console.log('code0',s1.codePointAt(0));//十进制 code0 134071 取4字节
  console.log('code0',s1.codePointAt(0).toString(16));//转成16进制  code0 20bb7 取4字节
  console.log('code1',s1.codePointAt(1));//code1 57271 防止乱码,自动取2字节
  console.log('code2',s1.codePointAt(2));//code2 97
}

{
  console.log(String.fromCharCode("0x20bb7"));
  console.log(String.fromCodePoint("0x20bb7"));
}

// of遍历

{
  let str='\u{20bb7}abc';
  for(let i=0;i<str.length;i++){
    console.log('es5',str[i]);
  }
  for(let code of str){
    console.log('es6',code);
  }
}
// 包含
{
  let str="string";
  console.log('includes',str.includes("c"));
  console.log('start',str.startsWith('str'));
  console.log('end',str.endsWith('ng'));
}
// 自我赋值
{
  let str="abc";
  console.log(str.repeat(2));
}
// 模板字符串
{
  let name="list";
  let info="hello world";
  let m=`i am ${name},${info}`;
  console.log(m);
}

// 补白 日期
{
  console.log('1'.padStart(2,'0'));
  console.log('1'.padEnd(2,'0'));
}
// 标签模板 过滤html标签,多语言模板转换 
{
  let user={
    name:'list',
    info:'hello world'
  };
  console.log(abc`i am ${user.name},${user.info}`);
  function abc(s,v1,v2){
    console.log(s,v1,v2);
    //这里处理
    return s+v1+v2
  }
}
// 对\进行转移,前面再加一个\
{
  console.log(String.raw`Hi\n${1+2}`);
  console.log(`Hi\n${1+2}`);
}

lession5-数值拓展

// 0b为二进制开头,八进制开头0o为
{
  console.log('B',0B111110111);
  console.log(0o767);
}

{
  console.log('15',Number.isFinite(15));//true
  console.log('NaN',Number.isFinite(NaN));//false
  console.log('1/0',Number.isFinite('true'/0)); //false
  console.log('NaN',Number.isNaN(NaN));//是否非数字
  console.log('0',Number.isNaN(0));//false

}
// 是否整数
{
  console.log('25',Number.isInteger(25));//true
  console.log('25.0',Number.isInteger(25.0));//true
  console.log('25.1',Number.isInteger(25.1));//false
  console.log('25.1',Number.isInteger('25'));//false
}
// js可以存储(-2^53,2^53),不包含端点,为安全数字,一定要是数字
{
  console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);
  console.log('10',Number.isSafeInteger(10));
  console.log('a',Number.isSafeInteger('a'));
}

// 取整
{
  console.log(Math.floor(4.2));//es5
  console.log(Math.ceil(4.1));//es5
  console.log(4.1,Math.trunc(4.1));
  console.log(4.9,Math.trunc(4.9));
}
// 判断正负
{
  console.log('-5',Math.sign(-5));
  console.log('0',Math.sign(0));
  console.log('5',Math.sign(5));
  console.log('50',Math.sign('50'));
  console.log('foo',Math.sign('foo'));
}

// 立方根
{
  console.log('-1',Math.cbrt(-1));
  console.log('8',Math.cbrt(8));
  console.log(Math.sqrt(8));//平方根
}

lesson6-数组拓展

ES6基础

//数组去重合并节
function combine(){ 
    let arr = [].concat.apply([], arguments);  //没有去重复的新数组 
    return Array.from(new Set(arr));
} 

var m = [1, 2, 2], n = [2,3,3]; 
console.log(combine(m,n));                     // [1, 2, 3]
{
  //数组去重合并节
  function combine() {
    let arr = [].concat.apply([], arguments);  //没有去重复的新数组 
    return Array.from(new Set(arr));
  }

  var m = [1, 2, 2], n = [2, 3, 3];
  console.log(combine(m, n));                     // [1, 2, 3]
}
// of
{
  let arr = Array.of(3, 4, 7, 9, 11, 'a', ...new Set([1, 1, , 2, 3]));
  console.log('arr=', arr);

  let empty = Array.of();
  console.log('empty', empty);
}
//from
{
  let p = document.querySelectorAll('p');
  let pArr = Array.from(p);
  pArr.forEach(function (item) {
    console.log(item.textContent);
  });

  console.log(Array.from([1, 3, 5], function (item) { return item * 2 }));
}

{
  console.log('fill-7', [1, 'a', undefined].fill(7));
  console.log('fill,pos', ['a', 'b', 'c'].fill(7, 1, 3));
}

// 遍历数组
{
  for (let index of ['1', 'c', 'ks'].keys()) {
    console.log('keys', index);
  }
  for (let value of ['1', 'c', 'ks'].values()) {
    console.log('values', value);
  }
  for (let [index, value] of ['1', 'c', 'ks'].entries()) {
    console.log('values', index, value);
  }
}
// 替换 使用频率不高
{
  console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));
}

// 查找
{
  console.log([1, 2, 3, 4, 5, 6].find(function (item) { return item > 3 }));
  console.log([1, 2, 3, 4, 5, 6].findIndex(function (item) { return item > 3 }));
}
// 包含
{
  console.log('number', [1, 2, NaN].includes(1));
  console.log('number', [1, 2, NaN].includes(NaN));
}

// 另外
// forEach map every some filter

lession7-函数拓展

ES6基础
arguments和rest参数区别

// 函数默认值,取代 x||x='aaa'
{
  function test(x, y = 'world'){
    console.log('默认值',x,y);
  }
  test('hello');
  test('hello','kill');
}
//如果前面有x,取前面的,没有就取外面了
{
  let x='test';
  function test2(x,y=x){
    console.log('作用域',x,y);
  }
  test2('kill');
}

//类似于arguments,rest参数
// Rest参数和arguments对象的区别:
// rest参数只包括那些没有给出名称的参数,arguments包含所有参数
// arguments 对象不是真正的数组,而rest 参数是数组实例,可以直接应用sort, map, forEach, pop等方法
// arguments 对象拥有一些自己额外的功能
// --------------------- 
// 原文:https://blog.csdn.net/chose_DoIt/article/details/85004059 

{
  function test3(...arg){
    for(let v of arg){
      console.log('rest',v);
    }
  }
  test3(1,2,3,4,'a');
}

{
  console.log(...[1,2,4]);
  console.log('a',...[1,2,4]);
}

{
  let arrow = v => v*2;
  let arrow2 = () => 5;
  console.log('arrow',arrow(3));
  console.log(arrow2());

}
//伪调用,什么是伪调用 (递归,嵌套)
{
  function tail(x){
    console.log('tail',x);
  }
  function fx(x){
    return tail(x)
  }
  fx(123)
}

lesson8-对象拓展

ES6基础

{
  // 简洁表示法
  let o=1;
  let k=2;
  let es5={
    o:o,
    k:k
  };
  let es6={
    o,
    k
  };
  console.log(es5,es6);

  let es5_method={
    hello:function(){
      console.log('hello');
    }
  };
  let es6_method={
    hello(){
      console.log('hello');
    }
  };
  console.log(es5_method.hello(),es6_method.hello());
}

{
  // 属性表达式
  let a='b';
  let es5_obj={
    a:'c',
    b:'c'
  };

  let es6_obj={
    [a]:'c'
  }

  console.log(es5_obj,es6_obj);

}

{
  // 新增API
  console.log('字符串',Object.is('abc','abc'),'abc'==='abc');
  console.log('数组',Object.is([],[]),[]===[]);//false 引用不一样

  console.log('拷贝',Object.assign({a:'a'},{b:'b'}));//浅拷贝 和...new Set([])
  // 浅拷贝:
  // 基本类型,直接拷贝;引用类型,拷贝引用;
  // 拷贝对象,只会拷贝自身的属性,不会拷贝继承的属性和不可枚举的属性;
  let test={k:123,o:456};
  for(let [key,value] of Object.entries(test)){
    console.log([key,value]);
  }
}

{
  // 扩展运算符
  let {a,b,...c}={a:'test',b:'kill',c:'ddd',d:'ccc'};
  // c={
  //   c:'ddd',
  //   d:'ccc'
  // }
}

lesson9-Symbol用法

声明永远不相等的值

ES6基础

{
  // 声明
  let a1=Symbol();
  let a2=Symbol();
  console.log(a1===a2);
  let a3=Symbol.for('a3');  //a3为key
  let a4=Symbol.for('a3'); //如果全局有a3,直接返回前面的a3
  console.log(a3===a4);
}

{
  let a1=Symbol.for('abc');
  let obj={
    [a1]:'123',
    'abc':345,
    'c':456
  };
  console.log('obj',obj);

  for(let [key,value] of Object.entries(obj)){
    console.log('let of',key,value);
  }

  Object.getOwnPropertySymbols(obj).forEach(function(item){
    console.log(obj[item]);
  })

  Reflect.ownKeys(obj).forEach(function(item){
    console.log('ownkeys',item,obj[item]);
  })
}

lesson10-set-map数据结构

ES6基础
做业务时,优先使用map,特别是复杂数据结构的,对唯一性有需求的使用set,最后考虑array,Object.

for(let [key,value] of list.entries()/keys()/values()){
    console.log('entries',key,value);
}

Set

数组去重合并

function combine(){ 
    let arr = [].concat.apply([], arguments);  //没有去重复的新数组 
    return Array.from(new Set(arr));
} 

var m = [1, 2, 2], n = [2,3,3]; 
console.log(combine(m,n));                     // [1, 2, 3]
// Set 元素不重复
{
  let list = new Set();
  list.add(5);
  list.add(7);

  console.log('size',list.size);
}

{
  let arr = [1,2,3,4,5];
  let list = new Set(arr);

  console.log('size',list.size);
}
// 去重
{
  let list = new Set();
  list.add(1);
  list.add(2);
  list.add(1);

  console.log('list',list);

  let arr=[1,2,3,1,'2'];
  let list2=new Set(arr);

  console.log('unique',list2);
}
// 几个方法
{
  let arr=['add','delete','clear','has'];
  let list=new Set(arr);

  console.log('has',list.has('add'));
  console.log('delete',list.delete('add'),list);
  list.clear();
  console.log('list',list);
}
// 遍历
{
  let arr=['add','delete','clear','has'];
  let list=new Set(arr);

  for(let key of list.keys()){
    console.log('keys',key);
  }
  for(let value of list.values()){
    console.log('value',value);
  }
  for(let [key,value] of list.entries()){
    console.log('entries',key,value);
  }

  list.forEach(function(item){console.log(item);})
}

// WeakSet 只能放对象 ; 弱引用,不会检测是否被垃圾回收 ;不能遍历
{
  let weakList=new WeakSet();

  let arg={};

  weakList.add(arg);

  // weakList.add(2);

  console.log('weakList',weakList);
}

// Map     key -- value
{
  // 第一种定义方法
  let map = new Map();
  let arr=['123'];

  map.set(arr,456);

  console.log('map',map,map.get(arr));
}

{
  // 第二种定义方式
  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);
}

{
  let weakmap=new WeakMap();

  let o={};
  weakmap.set(o,123);
  console.log(weakmap.get(o));
}

数据结构横向对比

map-array

{
  // 数据结构横向对比,增删改查
  let map = new Map();
  let array = [];
  
  // 增
  map.set('t',1);
  array.push({t:1});

  console.info('map-array',map,array);

  // 查
  let map_exist = map.has('t');
  let array_exist = array.find(item=>item.t);
  console.info('map-array',map_exist,array_exist);

  // 改
  map.set('t',2);
  array.forEach(item => item.t ? item.t = 2:'');
  console.info('map-array-modify',map,array);

  // 删
  map.delete('t');
  let index = array.findIndex(item => item.t);
  array.splice(index,1);
  console.info('map-array-empty',map,array);

}

set-array

{
  // set = array
  let set = new Set();
  let array = [];

  // 增
  set.add({t:1});

  console.info('set',set);

  // 查
  let set_exist = set.has({t:1});//这里是false,因为这个对象和上面那个是不一样的,是新生成的
  console.info('set',set_exist);

  // 改
  set.forEach(item => item.t?item.t=2:'');
  console.info('set',set);

  // 删
  set.forEach(item => item.t?set.delete(item):'');
  console.info('set',set);
}

map/set-Object

{
  let item = { t: 1 };
  let map = new Map();
  let set = new Set();
  let obj = {};

  // 增
  map.set('t', 1);
  set.add(item);
  obj['t'] = 1;

  console.info('map-set-obj',obj,map,set);

  // 查
  console.info({
    map_exist:map.has('t'),
    set_exist:set.has(item),
    obj_exist:'t' in obj
  });

  // 改
  map.set('t',2);
  item.t=2;//直接修改数据本身
  obj['t']=2;
  console.info('map-set-obj-modify',obj,map,set);

  // 删除
  map.delete('t');
  set.delete(item);
  delete obj['t'];
  console.info('map-set-obj-empty',obj,map,set);
}

lesson11-Proxy和Reflect(代理和反射)

ES6基础
改变直接操作Object的习惯,可以使用Reflect设置属性

{
  let obj={
    time:'2017-03-11',
    name:'net',
    _r:123
  };

  let monitor=new Proxy(obj,{
    // 拦截对象属性的读取
    get(target,key){
      return target[key].replace('2017','2018')
    },
    // 拦截对象设置属性
    set(target,key,value){
      if(key==='name'){
        return target[key]=value;
      }else{
        return target[key];
      }
    },
    // 拦截key in object操作
    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);

  monitor.time='2018';
  monitor.name='mukewang';
  console.log('set',monitor.time,monitor);

  console.log('has','name' in monitor,'time' in monitor);

  // delete monitor.time;
  // console.log('delete',monitor);
  //
  // delete monitor._r;
  // console.log('delete',monitor);
  console.log('ownKeys',Object.keys(monitor));

}

{
  let obj={
    time:'2017-03-11',
    name:'net',
    _r:123
  };

  console.log('Reflect get',Reflect.get(obj,'time'));
  Reflect.set(obj,'name','mukewang');
  console.log(obj);
  console.log('has',Reflect.has(obj,'name'));
}

应用:数据校验

{
  function validator(target,validator) {
    return new Proxy(target,{
      _validator:validator,
      set(target,key,value,proxy){
        if(target.hasOwnProperty(key)){
          let va = this._validator[key];
          console.log(key);
          console.log(va);
          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);
   person.name='eee'
}

lesson12-类和对象

ES6基础

{
  // 基本定义和生成实例
  class Parent{
    constructor(name='mukewang'){
      this.name=name;
    }
  }
  let v_parent=new Parent('v');
  console.log('构造函数和实例',v_parent);
}

{
  // 继承
  class Parent{
    constructor(name='mukewang'){
      this.name=name;
    }
  }

  class Child extends Parent{

  }

  console.log('继承',new Child());
}

{
  // 继承传递参数
  class Parent{
    constructor(name='mukewang'){
      this.name=name;
    }
  }

  class Child extends Parent{
    constructor(name='child'){
      super(name);
      this.type='child';
    }
  }

  console.log('继承传递参数',new Child('hello'));
}

{
  // getter,setter
  class Parent{
    constructor(name='mukewang'){
      this.name=name;
    }

    //longName这个不是方法,这是属性
    get longName(){
      return 'mk'+this.name
    }

    set longName(value){
      this.name=value;
    }
  }

  let v=new Parent();
  console.log('getter',v.longName);
  v.longName='hello';
  console.log('setter',v.longName);
}

{
  // 静态方法
  class Parent{
    constructor(name='mukewang'){
      this.name=name;
    }

    static tell(){
      console.log('tell');
    }
  }

  Parent.tell();

}

{
  // 静态属性
  class Parent{
    constructor(name='mukewang'){
      this.name=name;
    }

    static tell(){
      console.log('tell');
    }
  }

  Parent.type='test';

  console.log('静态属性',Parent.type);


}

lesson13-Promise

ES6基础
它是异步编程的解决方案

{
  // 基本定义
  let ajax=function(callback){
    console.log('执行');
    setTimeout(function () {
      callback&&callback.call()
    }, 1000);
  };
  ajax(function(){
    console.log('timeout1');
  })
}

{
  let ajax=function(){
    console.log('执行2');
    return new Promise(function(resolve,reject){
      setTimeout(function () {
        resolve()
      }, 1000);
    })
  };

  ajax().then(function(){
    console.log('promise','timeout2');
  })
}

{
  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');
  })
}

{
  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);
  });
}

//.then 自己写的测试
{

  let ajax = function (num) {
    return new Promise(function (resolve, reject) {
      if (num > 5) {
        resolve();
      } else if (num <= 5 && num >= 3) {
        reject();
      } else {
        // throw new Error('出错啦')
        reject(new Error('出错啦'));
      }
    })
  }
  ajax(6)
    .then(function () {
      console.log('11');
      return ajax(1);
    }, function () {
      console.log('reject1');
    })
    .then(function () {
      console.log('222');
    })
    .catch(function (err) {
      console.log('catch', err);
    })

}

Promise.all和Promise.race

 //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 showImg(imgs) {
    console.log(imgs);
    imgs.forEach(function (img) {
      document.body.appendChild(img);
    })
  }

  Promise.all([
    loadImg('http://clipart-library.com/images/BiarGpM4T.jpg'),
    loadImg('http://getwallpapers.com/wallpaper/full/e/6/0/826475-best-cartoon-wallpapers-2560x1440-laptop.jpg')
  ]).then(showImg)
  .catch(function (err) {
    console.log('catch',err);
  })
}


 //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 showImg(img) {
    console.log(img);
    img.width=100;
    let p = document.createElement('p');
    p.appendChild(img);
    document.body.appendChild(p);
  }

  Promise.race([
    loadImg('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559496717164&di=288f60d43b12bd29ee7b00361f37b397&imgtype=0&src=http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2F7CrlBDLFl4YLrIVhtEZZu2mVefODWXMibq4bUrZV22aGZy6aU3OxQWX6UvicMX2CShG6WicdIK9BEeMj4gibtfyc2w%2F640%3Fwx_fmt%3Dpng'),
    loadImg('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559496736977&di=7b445b2bd5e691743f908712b2b78acb&imgtype=0&src=http%3A%2F%2Fp1.ifengimg.com%2Ffck%2F2018_01%2F4b3586c88209a81_w640_h429.jpg')
  ]).then(showImg)
  .catch(function (err) {
    console.log('catch',err);
  })
}

lesson14-Iterator和for-of

ES6基础

{
  let arr=['hello','world'];
  let map=arr[Symbol.iterator]();
  console.log(map.next());
  console.log(map.next());
  console.log(map.next());
}

{
  let obj={
    start:[1,3,2],
    end:[7,9,8],
    [Symbol.iterator](){
      let self=this;
      let index=0;
      let arr=self.start.concat(self.end);
      let len=arr.length;
      return {
        next(){
          if(index<len){
            return {
              value:arr[index++],
              done:false
            }
          }else{
            return {
              value:arr[index++],
              done:true
            }
          }
        }
      }
    }
  }
  for(let key of obj){
    console.log(key);
  }
}

{
  let arr=['hello','world'];
  for(let value of arr){
    console.log('value',value);
  }
}

lesson15-Genertor

ES6基础

{
  // 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);
  }
}

//状态机 ABCABCABC
{
  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 state=async function (){
//     while(1){
//       await 'A';
//       await 'B';
//       await '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 draw = function (count) {
    console.info(`剩余${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)
}

长轮询(客服端状态要一直更新)

{
  // 长轮询
  let ajax = function* () {
    yield new Promise(function(resolve,reject) {
      setTimeout(() => {//这是AJAX请求
        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();
}

lessono15-用 async/await 来处理异步

Promise,async,await,fetch详解***

[js中!和!!的区别及用法](https://www.cnblogs.com/tison/p/8111712.html)

async/await基本理解及项目案例(结合Promise)

Async/Await替代Promise的6个理由

ES6基础

lesson16-Decorator(修饰器)

ES6基础

{
  //只读,不可修改
  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
}

应用:AD的显示或者点击

{
  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();
}

lesson17-模块化

ES6基础

// export let A=123;
//
// export function test(){
//   console.log('test');
// }
//
// export class Hello{
//   test(){
//     console.log('class');
//   }
// }


//import {A,test,Hello} from './test'
//console.log(A,test,Hello);

//import * as lesson from './test'
//console.log(lesson.A,lesson.Hello);

//推荐下面这种,导入的时候可以任意名称
let A=123;
let test=function(){
  console.log('test');
}
class Hello{
  test(){
    console.log('class');
  }
}

export default {
  A,
  test,
  Hello
}
//import lesson from './test'
//console.log(lesson.A,lesson.Hello);


华丽的分割线


Other

避免没有传入回调函数引起错误callback&&callback.call()

{
  let ajax = function (callback) {
    console.log('执行');
    setTimeout(() => {
      callback&&callback.call()
    }, 1000);
  }
}

throw new Error(‘出错啦’)抛出错误

http是无状态的