es6常用点记录

let

      /* let 声明变量 */
      /* es6相对于es5的全局和局部作用域,多了一个块作用域,块作用域里声明的变量声明周期只在本块内 */
      let a = 1;
      console.info(a); // 输出1
      for (let i=1;i<10;i++) {
        console.info(i); // 在块内是可以正常使用的
      }
      console.info(i); // 异常,ReferenceError: i is not defined
      // let是不能重复定义的

const

      /* const 声明常量*/
      /* const也是块作用域的 */
      const PI = 3.14159265
      const constObj = {
        key1: 'value1',
        key2: 'value2'
      }
      console.info(PI); // 输出3.14159265
      console.info(constObj) // 输出Object { key1: "value1", key2: "value2" }

      PI = 1 // 错误的,只读,不能修改
      constObj = {key3: 'value3'} // 错误的,只读,不能修改
      constObj.key1 = 1 // 可以修改,并不是因为常量可以修改,而是因为对象是引用类型的,这里只是修改对象的值,并没有修改对象的引用
      console.info(constObj) // 输出Object { key1: 1, key2: "value2" }

解构赋值

      /* 解构赋值 */
      /* 左边一个结构,右边一个结构,左边与右边解开结构一一赋值 */
      /* 变量交换、方法返回数组中存有多个变量、 只提取数组中的某些值、重组数组等场景*/

      // 数组解构赋值
      let a,b,c;
      [a,b,c] = [1,2,3];
      console.info(a); //输出1
      console.info(b); //输出2
      console.info(c); //输出3

      [a,b,c =4] = [1,2];
      console.info(a); //输出1
      console.info(b); //输出2
      console.info(c); //输出4,如果没有默认值,匹配不上,就是undefined

      let d,e,f;
      [d,e,...f] = [1,2,3,4,5,6,7,8,9,10];
      console.info(d); //输出1
      console.info(e); //输出2
      console.info(f); //Array [ 3, 4, 5, 6, 7, 8, 9, 10 ]

      // 对象解构
      let obj1,obj2;
      ({obj1,obj2} = {obj1: 'val1', obj2: 'val2'});
      console.log(obj1); //输出val1
      console.log(obj2); //输出val2

字符串

  • 字符串unicode扩展
      /* 字符串unicode扩展 */
      // \u表示后面是要输出一个unicoide编码对应的字符
      let unicoideStr1 = '\u0061'
      let unicoideStr2 = '\u20334'
      //第一个正常输出是因为在二字节范围内的编码(0x0000-0xffff),第二个已经超过了两个字节的unicode编码表,会把前四位当成一个字符,最后一位当成一个字符
      console.info(unicoideStr1,unicoideStr2) // a ″4

      //显示两个字节以上的unicode编码,需要把编码用{}包起来
      let unicoideStr3 = '\u{20334}'
      console.info(unicoideStr1,unicoideStr3) // a ?

      let spacStr = '?'
      // es5中把超过两个字节长度编码的字符处理为4个字节,就是两个字符,输出2
      console.info(spacStr.length) //输出2

      let spacStrTest = '?a'
      console.info(spacStrTest.length); //输出3

      console.info("第一个字符",spacStr.charAt(0)) //输出 第一个字符 乱码
      console.info("第二个字符",spacStr.charAt(1)) //输出 第一个字符 乱码
      console.info("第二个字符编码",spacStr.charCodeAt(0)) //第一个字符编码 55360
      console.info("第二个字符编码",spacStr.charCodeAt(1)) //第二个字符编码 57140
      // 显然,这不是想要的结果,因此es5中处理这种字符是不正确的

      console.info(spacStrTest.codePointAt(0)) //输出 131892
      console.info(spacStrTest.codePointAt(0).toString(16)) //输出 20334
      console.info(spacStrTest.codePointAt(1)) //输出 57140
      console.info(spacStrTest.codePointAt(2)) //输出 97

      //es5中根据编码取字符,大于两个字节的不能正常显示
      console.info(String.fromCharCode('0x20334')) //输出乱码
      //es6中根据编码取字符
//      console.info(String.fromCodePoint('0x20334')) //输出 ?

      //es5的循环不能正确取值
      for(var i=0;i<spacStrTest.length;i++){
        console.info(spacStrTest[i]); //输出两个乱码和一个a
      }

      //es6的循环可以正确取值
//      for(let char of spacStrTest){
//        console.info(char); //输出 ? a
//      }
  • 字符串其他扩展
 /* 字符串其他扩展 */
      let otherStrTest = 'string'
      //是否包含
      console.info(otherStrTest.includes('in')) //输出true
      //是否起始
      console.info(otherStrTest.startsWith('str')) //输出true
      //是否结尾
      console.info(otherStrTest.endsWith('ing')) //输出true

      //复制10次
      console.info(otherStrTest.repeat(10)) //输出stringstringstringstringstringstringstringstringstringstring (一共10次)

      //字符串模板
      let name = 'thatway'
      let age = '18'
      let man = `name is ${name},age is ${age}`
      console.info(man) //输出name is thatway,age is 18

      //padStart、padEnd 接收两个参数,第一个参数是长度,不够就补白,第二个是补白用的字符
      let simpleStr = '1'
      let leftPaddingStr = simpleStr.padStart(2,'0')
      let rightpaddingStr = simpleStr.padEnd(2,'0')
      console.info(leftPaddingStr, rightpaddingStr) //输出01 10

      // raw会ie所有字符转义,就是在特殊字符钱加一个\,使其正常输出
      console.info(String.raw('hello\nworld')) // 输出hello\nworld
      console.info('hello\nworld')// 输出hello
      //world

数组

   /* 数组 */
//      let arrTest1 = Array.of(1,2,3,4,5)
//      console.info(arrTest1) //输出[1,2,3,4,5]

//      let arr = [1,2,3,4,5]
//      let arrTest2 = Array.from(arr)
//      console.info(arrTest2) //输出[1,2,3,4,5]
//      let arrTest3 = Array.from(arr,function(item){return item*2})
//      console.info(arrTest3) //输出[2,3,6,8,10]

      //fill,把数组中元素全部替换掉
      let arrFill1 = [1,2,3]
      console.info(arrFill1.fill(0)) //输出[0,0,0]

      //fill,把数组中元素从第1个开始替换到第3个
      let arrFill2 = [1,2,3,4,5]
      console.info(arrFill2.fill(0,1,3)) //输出[ 1, 0, 0, 4, 5 ]

      //遍历
//      for(let [index,value] of ['1','2','3'].entries()){
//          console.info(index,value)
//      }

      //find,查找元素,注意,只返回第一个符合的
      let arrTest3 = [1,2,3,4,5]
      console.info(arrTest3.find(function(item){return item > 3})) //输出4
      console.info(arrTest3.findIndex(function(item){return item > 3})) //输出3

      //是否包含某个值
      let arrTest4 = [1,2,3,4,5,NaN]
      console.info(arrTest4.includes(3)) // 输出true
      console.info(arrTest4.includes(NaN)) // 输出true

函数

     /* 函数 */

      //参数默认值
      function test1(x,y='123'){
        console.info(x,y);
      }
      test1('abc') // 输出abc 123
      test1('abc','def') // 输出abc def

      //作用域
      let x = 'abc'
      function test2(x,y=x){
        console.info(x,y)
      }
      test2('123') //输出123 123
      test2() //输出 undefined undefined
      function test3(z,y=x){
        console.info(z,y)
      }
      test3('123') //输出123 abc
      test3() //输出 123 undefined

      //rest参数,参数不确定个数,如果生命了rest参数,不能再声明其他参数了
      function test4(...params){
         console.info(params)
      }
      test4(1,2,3,4,5) //Array [ 1, 2, 3, 4, 5 ]
      test4(1) //Array [ 1 ]
      test4() //[]

      // ...数组 可以把数组里的值拆散成值
      console.info(...[1,2,3,4,5]) //1 2 3 4 5
      console.info('a',...[1,2,3,4,5])//a 1 2 3 4 5

      //箭头函数
      //es5的函数声明
      function arrow5(){
          console.info('arrow')
      }

      //es6的函数声明
      //方法体只有一行的时候可以不写{}
      let arrow6 = ()=>console.info('arrow')

      arrow5() //arrow
      arrow6() //arrow

      let arrowTest = (x,y)=>{
          console.info(x)
          console.info(y)
      }
      arrowTest(1,2) //1 2
      //--

      //伪调用,优化嵌套、依赖函数,可提高性能
      let fun1 = (x)=>{
        console.info('fun1')
      }

      let fun2 = (x)=>{
        return fun1(x)
      }
      console.info(fun2('abc'))

对象

   /* 对象 */
      let name= "thatway"
      let age= 18
      //es5的对象写法
      let man5 = {
        name:name,
        age:age
      }
      //es6中可以将属性名与变量名相同的简写成一个
      let man6 = {
        name,
        age
      }
      //结果是一样的
      console.info(man5,man6);

      //es5对象中的方法写法
      let man5_method = {
        play: function(){
            console.info("玩")
        }
      }

      //es6对象中的方法写法
      let man6_method = {
       play(){
         console.info("玩")
       }
      }
      //--

//      let param = 'sex'
//      //属性表达式
//      let man5_obj = {
//        name: 'thatway',
//        age: 18
//      }
//
//      //es6属性名可以用变量
//      let man6_obj = {
//        name: 'thatway',
//        age: 18,
//        [param]: 'boy'
//      }
//      console.info(man5_obj,man6_obj)

//      //比较两个对象是否是同一个,等同于===,注意引用类型的比较
//      console.info(Object.is('abc','abc'))

Symbol

声明不想等的两个值,保证唯一性,babel不支持此API的编译,略过了,知道有这么回事先

Set

      /* set */
      let list1 = new Set()
      list1.add("1");
      list1.add("2");
      console.info(list.size) //2

      let arr = [1,2,3,4,5]
      let list2 = new Set(arr)
      console.info(list2.size) //5

      let list3 = new Set()
      list3.add(1)
      list3.add(2)
      list3.add(1)
      //set中的值必须唯一,因此忽略第二个2,可以利用这个特性来去重
      //去重的时候不会做类型的转换,比如1'1'是可以同时存在的
      console.info(list3.size) //2

      //setadd、has、delete、clear几个方法
      list3.has(1) //是否含有某个元素
      list3.delete(1) //删除1 返回true代表成功
      list3.clear() //清空

      //遍历
      for(let key of list3.keys()){
        console.info(key)
      }
      for(let value of list3.values()){
        console.info(value)
      }
      for(let [key,value] of list3.entries()){
        console.info(key,value)
      }
      list3.forEach(function(item){
          console.info(item)
      })

      //在webpack里为什么编译不通过呢,总觉得应该是配置的问题,有空查一下
      //补充,这个问题是因为babel只转换es6的句法,不转换新的API...比如比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,解决这个问题的办法是引入babel-polyfill,它提供了es6语法的兼容。
      $ npm install --save babel-polyfill

WeakSet

//WeakSet 和Set的区别是只能放对象,WeakSet是弱引用类型,可以防止内存泄露,其中的对象不存在引用时会被垃圾回收释放内存
      //WeakSet 没有size属性 只有三个方法add、delete、has
      let list_w = new WeakSet();
      let obj = {
          title : '111'
      }
      list_w.add(obj)

      //异常,TypeError: [object WeakSet] is not iterable!
      //WeakSet不支持遍历
//      for(let item of list_w){
//        console.info(item)
//      }

      //异常,TypeError: WeakSet value must be an object, got the number 1
      list_w.add(1)

Map

 //map
      //map里放的是键值对,键可以是任何类型
      let mapTest1 = new Map()
      mapTest1.set("key","value")
      console.info(mapTest1.get("key")) // 输出value

      //用数组作为key
      let arrKey = [1,2,3,4,5];
      mapTest1.set(arrKey,"value2")
      console.info(mapTest1.get(arrKey)) // 输出value2

      // 用数组构造函数
      let mapTest2 = new Map([['key1','abc'],['key2','def']]);
      console.info(mapTest2.get('key1')) // abc

      //map长度
      console.info(mapTest2.size) //2

      //其他方法
      mapTest2.delete("key")
      mapTest2.clear()

      //遍历与set一样

WeakMap

WeakMap和WeakSet的特性一样,键必须是对象。

Proxy

      /* proxy */
      let objTest1 = {
         name: 'thatway',
         age: '18'
      }

      //代理objTest1,让用户去操作proxyTest,实际数据是存在于objTest1
      //第一个参数是要代理的对象
      //第二个参数是要拦截的各种配置
      let proxyTest = new Proxy(objTest1,{
        //拦截对象的读取
        get(target,key){
          return target[key]+"哦"
        },
        //拦截赋值操作
        set(target,key,value){
          return target['key']= value+"哦"
        },
        //拦截in操作,是否存在
        has(target,key){
           if(key == 'name'){
              return false
           }
        },
        //拦截delete
        deleteProperty(target,key){
          if(key == 'name'){
            delete target[key]
            return true
          }else{
            return target[key]
          }
        },


      })
      console.info(proxyTest.name) //thatway哦
      proxyTest.name = "wp"
      console.info(proxyTest) //name值被设置为wp哦
      console.info(name in proxyTest); //false
      console.info(delete proxyTest.name) //true
      console.info(delete proxyTest.age) //true
      console.info(proxyTest) //对象中没有了name,age还存在

proxy的操作
- get
get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy[‘foo’]。
- set
set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy[‘foo’] = v,返回一个布尔值。
- has
has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
- deleteProperty
deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
- ownKeys
ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
- getOwnPropertyDescriptor
getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
- defineProperty
defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
- preventExtensions
preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
- getPrototypeOf
getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
- isExtensible
isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
- setPrototypeOf
setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
- apply
apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。
- construct
construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(…args)。

reflect

refect方法与proxy一一对应。

     /* reflect */
      //字母是反射的意思
      //Reflect不用new
      console.info(Reflect.get(objTest,'name')) //thatway
      console.info(Reflect.set(objTest,'key','value'))
      console.info(objTest)

reflect的设计目的,阮大神的文档中是这么说的:
1、 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。

2、修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。

3、让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。

4、Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

Proxy与Reflex结合实例

      //声明一个方法,返回值是一个代理对象,参数是实际对象和验证规则对象
      //其目的是为了给原对象做一些列数据格式验证,用户在使用对象时拿到的实际上是代理对象,而不是实际对象
      //这样的话就能够在用户填充数据时做一层拦截
      let validator = (obj,validatorConfig)=> {
        return new Proxy(obj,{
            _validatorConfig:validatorConfig,
          set(target,key,value,receiver){
            if(target.hasOwnProperty(key)){
              let validateAction = this._validatorConfig[key];
              if(!!validateAction(value)){
                return Reflect.set(target,key,value,receiver)
              }else{
                throw Error(`不能设置${key}到${value}`)
              }
            }else{
              throw Error(`${key}不存在`)
            }
          }
        });
      }

      //针对man对象的数据验证
      const manValidator = {
          name(val){
            return typeof val === 'string'
          },
          age(val){
            return typeof val === 'number' && val > 18
          }
      }

      //创建对象
      class Man{
         constructor(name,age=18){
           this.name= name
           this.age= age
           return validator(this,manValidator)
        }
      }

      let manTest = new Man()
//      manTest.name = 123 // Error: 不能设置name到123
      manTest.name = 'thatway'
      console.info(manTest) // 输出对象,其中name为thatway,age为18

//      manTest.age = '20'// Error: 不能设置age到20
      manTest.age = 20
      console.info(manTest) // 输出对象,其中name为thatway,age为20

      manTest.sex = 'boy' // Error: sex不存在

class

es6中定义类的关键字是class,不是Class

      /* class */
      //定义类
      class Parent{
         constructor(name='thatway'){
          this.name= name
         }
      }
      //实例化
      let thatway = new Parent('wp');
      console.log(thatway); //打印 Object { name: "wp" }

      //继承类
      class Child extends Parent{

      }
      let child1 = new Child()
      console.info(child1) //Object { name: "thatway" }
      let child2 = new Child('tutu')
      console.info(child2) //Object { name: "tutu" }

      class Tutu extends Parent{
        constructor(name='child',type){
          //子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象
          super(name)
          this.type = type
        }
      }
      let tutu1 = new Tutu()
      console.info(tutu1) //Object { name: "child", type: undefined }
      let tutu2 = new Tutu('tutu','boy')
      console.info(tutu2)//Object { name: "tutu", type: "boy" }

      //getter、setter
      class P{
          constructor(name='thatway'){
            this.name = name
          }
          set title(value){
            this.name = value
          }
          get title(){
            return this.name
          }
      }

      let p = new P()
      p.title = '123'
      console.info(p.title)//123
      console.info(p)//Object { name: "123" }

      //静态方法
      class S{
        constructor(name='thatway'){
          this.name = name
        }
        static sing(){
          console.info('金色的河蓝色的海,都有我们快乐的身影...')
        }
      }
      console.info(S.sing()) //金色的河蓝色的海,都有我们快乐的身影...

      //静态属性,静态属性不使用static关键字,目前的方案是直接赋值
      S.age = 18
      console.info(S.age) //18

promise

     // 使js异步操作更加合理强大
      //es5中ajax回调模式
      function ajax5(callback){
        console.info("ajax5-1")
        setTimeout(function(){
          callback&&callback()
        })
        console.info("ajax5-2")
      }
      ajax5(function(){
        console.info("callback5");
      })

      //es6 promise方式
      let ajax6 = ()=> {
        console.info("ajax6-1")
        return new Promise((resolve,reject)=>{
          console.info("ajax6-2")
          setTimeout(()=>{
            resolve()
          },1000)
        })
      }
      ajax6().then(()=>{
        console.info("callback6")
      })

      let ajaxSencond = ()=>{
        return new Promise((resolve,reject)=>{
          return reject(new Error('second error'))
        })
      }

      //promise实例的then方法返回一个新的promise实例,所以可以链式调用,这样就可以将多个异步操作变得有序
      //第一个then返回的结果,会作为第二个then的参数
      //then是有顺序的
      ajax6().then(((data)=>{
        console.info("ajax6 succ")
        return "ajax6 rs"
      }),(data)=>{
        console.info("ajax6 error")
      }).then((data)=>{
        console.info("第二个then的resolve接收到的参数,可以拿着异步返回的结果做下面的逻辑了:"+data)
        ajaxSencond().then((data)=>{
            console.info("ajaxSencond succ")
        },(data)=>{
            console.info(data)
        })
      },(data)=>{
        console.info("ajax6 error")
      })

      //异常的捕获,建议用catch
      ajaxSencond().then((data)=>{

      },(data)=>{
          console.info("异常在这里出现-回调")
      })

      ajaxSencond().then((data)=>{

      }).catch(function(data){
        console.info("异常在这里出现-catch")
      })

      //all 所有的promise都返回结果以后才会then,如果其中一个失败了,则直接用失败的结果
      let pro1 = new Promise((resolve,reject)=>{
        return resolve("data1")
      })

      let pro2 = new Promise((resolve,reject)=>{
        return resolve("data2")
      })
      Promise.all([pro1,pro2]).then(([data1,data2])=>{
         console.info(data1,data2)
      }).catch(function(error){
        console.info(error)
      }) //data1 data2

      let pro3 = new Promise((resolve,reject)=>{
        return reject(new Error('pro3 error'))
      })

      let pro4 = new Promise((resolve,reject)=>{
        return resolve("data4")
      })
      Promise.all([pro3,pro4]).then(([data3,data4])=>{
        console.info(data3,data4)
      }).catch(function(error){
        console.info(error)
      }) //Error: pro3 error

      //raceall不一样的是,哪个先返回结果就用哪个的结果,其他的不用了
      let pro5 = new Promise((resolve,reject)=>{
        setTimeout(function(){
          return resolve("data5")
        },100)

      })

      let pro6 = new Promise((resolve,reject)=>{
        return resolve("data6")
      })

      Promise.race([pro5,pro6]).then((data)=>{
        console.log(data)
      }).catch((data)=>{
        console.log(data)
      }) //data6

iterator

      /* Iterator */
      //数据集合结构的统一遍历方法
      //具有Symbol.iterator属性的数据结构就可以使用for of循环遍历
      function Obj(value) {
        this.value = value;
        this.next = null;
      }

      Obj.prototype[Symbol.iterator] = function() {
        var iterator = { next: next };

        var current = this;

        function next() {
          if (current) {
            var value = current.value;
            current = current.next;
            return { done: false, value: value };
          } else {
            return { done: true };
          }
        }
        return iterator;
      }

      var one = new Obj(1);
      var two = new Obj(2);
      var three = new Obj(3);

      one.next = two;
      two.next = three;

      for (var i of one){
        console.log(i); // 1, 2, 3
      }

//      原生具备 Iterator 接口的数据结构如下。
//
//      Array
//      Map
//      Set
//      String
//      TypedArray
//      函数的 arguments 对象
//      NodeList 对象

Gernerator

      /* Generator */
      // generator是es6中的另一个异步解决方法

      //基本定义
      let tell = function* (){
        yield 'a';
        yield 'b';
        return 'c'
      }

      let rs = tell()
      console.info(rs.next()) //Object { value: "a", done: false }
      console.info(rs.next()) //Object { value: "b", done: false }
      console.info(rs.next()) //Object { value: "c", done: true } 有return的时候done会变为true
      console.info(rs.next()) //Object { value: undefined, done: true }

      //Generator返回的就是一个Iterator
     let obj = {}
     obj[Symbol.iterator] = function* (){
       yield '1';
       yield '2';
       return
     }

      for(let val of obj){
        console.info(val)
      }

      //Generator应用场景:状态机
      //123三种状态
      let state = function* (){
        while (true){
           yield 1;
           yield 2;
           yield 3;
        }
      }

      let status = state();
      for(let i = 0;i<= 10;i++){
        console.info(status.next()) //一直是123依次输出
      }

      //抽奖次数限制
      let action = (count)=> {
        //抽一次奖品
        console.info(`剩余${count}次`)
      }

      let timesController = function* (count){
         while(count > 0){
           count --
           yield action(count)
         }
      }

      let times = 5
      let lottry = timesController(times)
      lottry.next()
      lottry.next()
      lottry.next()
      lottry.next()
      lottry.next()
      lottry.next()

      //长轮询实例
      let ajax = function* (){
         //yield返回一个promise实例
         yield new Promise((resolve,reject)=> {
           //异步耗时1秒钟后返回结果  
           setTimeout(()=>{
             return resolve('ok')
           },1000)
         })
      }
      //查询方法
      let pull = ()=> {
        //拿到Generator
        let generator = ajax()
        //执行ajax
        let step = generator.next()
        // step.value是返回的promise
        step.value.then((data)=>{
           //如果结果不是期望的,1秒以后再一次调用,直到结果是期望的 
           if(data != 'ok'){
             setTimeout(()=>{
               console.info("等待1秒后再轮询")
               pull()
             },1000)
           }else{
              console.info('结束了:'+data)
           }
        })
      }
      //开始拉取数据 
      pull()

Decorators

这个api需要插件支持

npm i babel-plugin-transform-decorators-legacy -D

.babelrc中添加插件

"plugins": ["transform-decorators-legacy"]
      /* Decorator 修饰器 */
      // 是一个函数
      // 修改行为(可以修改或者扩展行为)
      // 类的行为 (只能在类上使用)
      // 类似于java的注解

      //声明一个修饰器
      let decoratorReadOnly = function(target,name,descriptor){
        descriptor.writable = false
        return descriptor
      }

      //修饰某一个类的行为
      class Test{
        @decoratorReadOnly
        getName(){
          return 'thatway'
        }
      }

      let test = new Test()
      test.getName = function(){
         return 'new'
      }//TypeError: "getName" is read-only

      //也可以放在类前修饰类
      let typeDecorator = function(target,name,descriptor){
        target.name = 'a'
      }

      @typeDecorator
      class Empty{}
      console.info('修饰类',Empty.name) //"name" is read-only

      //日志埋点
      let log = (type)=> {
        return function(target,name,descriptor){
          let src_method = descriptor.value
          descriptor.value =(...args)=>{
            src_method.apply(target,args)
            console.info(`log ${type}`)
          }
        }
      }

      class logTestObj {
        @log('method1')
        method1(){
          console.info('method1')
        }
        @log('method2')
        method2(){
          console.info('method2')
        }
      }

      let o = new logTestObj()
      o.method1()
      o.method2()

core-decorators包已经封装了常见的修饰符

npm i core-decorators

模块

模块主要涉及到import和export的语法,有几种不同情况下不同的写法。

学习资料

关于es6的入门,阮一峰大神已经整理的非常易懂了:

阮大神的babel介绍和ES6手册
http://www.ruanyifeng.com/blog/2016/01/babel.html
http://es6.ruanyifeng.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值