• ES6 新特性


    ES6新特性

    1.变量扩展

      (1).var 的问题:可以重复声明;  无法限制修改;  没有块级作用域;

      (2).新加let: 不能重复声明;  变量—可以重新进行赋值;  块级作用域;

      (3).新加const:不能重复声明;  常量—不可以重新进行赋值;  块级作用域;

            //var a=1;
            //var a=2;
            //alert(a); //可以重复声明
                
            //let a=1;
            //let a=2;
            //alert(a);//不可以重复声明
                
            const a=1;
            const a=2;
            alert(a);//和let一样

      块级作用域与函数声明

        块级作用域有什么用?

        <script>
             window.onload=function(){
                 var aBtn=document.getElementsByTagName("input");                 
                 for (var i=0;i<aBtn.length;i++)
                 {
                     aBtn[i].onclick=function()
                     {
                         alert(i);    
                     }
                 }                 
             }                          
        </script>
    
        <input type="button" value="按钮1">
        <input type="button" value="按钮2">
        <input type="button" value="按钮3">
        //都会弹出3

      以前解决的办法:用密封空间:

            <script>
                 window.onload=function(){
                     var aBtn=document.getElementsByTagName("input");
                     
                     for (var i=0;i<aBtn.length;i++)
                     {
                         (function(i){  //封密空间
                             aBtn[i].onclick=function()
                         {
                             alert(i);    
                         };
                         })(i);                     
                     }                 
                 }                          
            </script>   
    // 用一个封密空间,利用函数加了一级作用域。
    var 只认函数这一层。

      现在:直接改成let即可:

            <script>
                 window.onload=function(){
                     var aBtn=document.getElementsByTagName("input");                 
                     for (let i=0;i<aBtn.length;i++)  //本身就是一层作用域
                     {                 
                         aBtn[i].onclick=function()
                         {
                             alert(i);    
                         };                                          
                     }                 
                 }                          
            </script>  
            <input type="button" value="按钮1">
            <input type="button" value="按钮2">
            <input type="button" value="按钮3">        
         //把var 改成 let 即可,for循环就是一个语法块。

    总结:let 完全可以取代const

    2.函数扩展

     (1)箭头函数

          window.onload=function()
          {
             alert("abc")
          }
                
           window.onload=()=>{
              alert("abc")
           }

      箭头函数还有有两个特性:

    • 如果只有一个参数,“()”小括号可以省;
    • 如果只有一个return, “ { } ”花括号可以省;
      /*let show=function(a){
          return a*2;
      }*/
      //可以简写成            
      let show=a=> a*2;                            
      alert(show(12))

     (2)函数的参数

    • 参数扩展/展开;
      1.收集剩余参数,  形式:三个点,一个任意名字 ...args
       function show(a,b,...args){
            alert(a);
            alert(b);
            alert(args);
        }
        show(1,2,3,4,5,6)
                  
        //1     
        //2   
        //3,4,5,6
      注意 ...args 必须放在最后一个

      2.展开数组:展开后的效果,相当于直接数组的内容写在这儿。
        let arr1=[1,2,3];
        let arr2=[5,6,8];            
        let arr=[...arr1,...arr2];            
        //  let arr=[1,2,3,5,6,8];   相当于这么写
                  
        alert(arr);
                  
        //1,2,3,4,5,6,7,8
    • 默认参数; ——传了听你的,不传听我的
        function show(a,b=88,c=99){         
           console.log(a,b,c)
        }
              
         show(1,2)
      
        // 1,2,99

    3.变量解构赋值

    • 左右两边结构必须一样;
    • 右边必须是个内容;
    • 声明和赋值不能分开;
       //数组:
        /*let arr=[1,2,3];            
         let a=arr[0];
         let b=arr[1];
         let c=arr[2];*/
                  
        //可以写成这样
         let [a,b,c] = [1,2,3]
                  
         console.log(a,b,c);   //1,2,3
        //--------------------------------------------------------------------------------------
        //json
        let {a,b,c} = {a:1,b:2,c:4}
        console.log(a,b,c);  //1,2,3

       

    4.数组扩展

     添加了四个方法:map  reduce  filter  forEach

     (1)map — 映射  —  一个对一个

      let arr=[10,2,3];            
      let result=arr.map(function(item){
        //alert(item)
        return (item*2)
      })
      alert(result)    // 20,4,6
    
      //可以写成箭头函数
      let arr=[10,2,3];             
      let result=arr.map(item=>item*2);
      alert(result)    // 20,4,6

    --------------------------------------------------------------------------------------

    //在写一个应用
      let score=[90,40,58,60];
      let result=score.map(item=>item>=60?"及格":"不及格");
      alert(result)  //及格,不及格,不及格,及格

    (2)reduce  — 汇总   — 一堆出来一个  

           // 总和 
            var arr=[88,12,20];
            
            let result=arr.reduce(function(tmp,item,index){
              //alert(tmp+','+item+","+index) 三个参数分别代表:中间结果、每次的数、下标
                return tmp+item;
            })
            alert(result)  // 120
            
            
            //求平均数
            let result =arr.reduce(function(tmp,item,index){    
              if(index!=arr.length-1)  //不是最后一次
              {
                return tmp+item;   //先求和
              }
              else
              {
                return (tmp+item)/arr.length;   //去求平均数
              }    
            })
            alert(result) // 40

    (3)filter —  过滤器

      //求能被三整除的
      let arr=[88,12,20,11];
      let result=arr.filter(item=>item%3==0)
      alert(result)  //12

    (4)forEach  —  循环(迭代)

      let arr=[12,10,44];          
      arr.forEach((item,index)=>
      { 
          alert(index+":"+item)
      });  

    // 0:12
    // 1:10
    // 2:44

    5.字符串扩展

    • 添加了两个新方法 :startsWith 起始,endsWith 结尾
       //startsWith 
      let str="http://www.baidu.com"; if(str.startsWith("http://")){ alert("普通网址") } else if(str.startsWith("https://")) { alert("保密网址") } else { alert("其他网址") } //普通网址
          //endsWith 
          let str="xxx.png";  
          if(str.endsWith("txt"))
          {
              alert("文本文件");
          }
          else if(str.endsWith("png"))
          {
              alert("图片文件");
          }
          else
          {
              alert("其他");
          }
          //图片文件        
    • 字符串模板:字符串连接
      1.可以把东西塞到字符串里 ${ }
      2.可以换行
          let title="标题";
          let content="内容";
          
          let str=`<div>
          <h1>${title}</h1>
          <p>${content}</p>
          </div>`;
          alert(str);
          
          //结果:
          <div>
          <h1>标题</h1>
          <p>内容</p>
          </div> 

    6.面向对象

       之前的缺点:构造函数和类不区分

       主要变化:1.class关键字,构造器(constructor) 和类分开了;

            2.class 里直接加方法。

    //之前的
    function User(name,pass)
    {
        this.name=name;
        this.pass=pass;
    };
    User.prototype.showName=function(){
        alert(this.name);
    };
    User.prototype.showPass=function(){
        alert(this.pass);
    };
    var Obj=new User("wy","123");
    Obj.showName();
    Obj.showPass();
    // 结果 wy 123
    
    
    //ES6
    class User{
        constructor(name,pass){   //constructor 构造器
            this.name=name;
            this.pass=pass;
        }
        
        showName(){
            alert(this.name)
        }
        showPass(){
            alert(this.pass)
        }
    }
    var Obj=new User("wy","123");
    Obj.showName();
    Obj.showPass();
    // 结果 wy 123

     继承:

      extends:扩展,延展

      super:超类,父类

         // 之前的继承写法
            function User(name,pass)
            {
                this.name=name;
                this.pass=pass;
            }
            
            User.prototype.ShowName=function(){
                alert(this.name);
            }
            
            User.prototype.ShowPass=function(){
                alert(this.pass);
            }
            
            function VipUser(name,pass,level)
            {
                User.call(this,name,pass);
                this.level=level;
            }
            
            VipUser.prototype=new User();
            VipUser.prototype.constructor=VipUser;  //会改变constructor指向,需要手动恢复
            
            /*for(var i in User.prototype)
            {
                VipUser.prototype[i]=User.prototype[i];
            }*/
            
            VipUser.prototype.ShowLevel=function(){
                alert(this.level)
            }
                            
            var obj=new VipUser("wy","123","3");
            obj.ShowName();
            
            obj.ShowPass();
            
            obj.ShowLevel();
            // wy
            // 123
            // 3
            
            
            //---------------------------------------------------------------------------------------------------------------
            
            //ES6
            class User{
                constructor(name,pass){
                    this.name=name;
                    this.pass=pass;
                }
                showName(){
                    alert(this.name)
                }
                showPass(){
                    alert(this.pass)
                }
            }
            
            class VipUser extends User{     //用extends
                constructor(name,pass,level){    
                    super(name,pass);   //用 super 从父类上继承属性
                    
                    this.level=level;                                        
                }
                
                showlevel(){
                    alert(this.level);
                }
            }
            
            var Obj=new VipUser("wy","123","3");
            Obj.showName();
            Obj.showPass();
            Obj.showlevel();
            // wy 
            // 123 
            //3

    7.json扩展

    • 1. json 对象 新加了两个方法
       (1). json.stringify : 把json 变成字符串的方法。
        var json={a:12,b:11};            
        var str='https://www.baidu.com/path/user? 
        data='+encodeURIComponent(JSON.stringify(json));  //字符串        
        alert(str)

       (2). json.parse : 把字符串变成json。
        var str='{"a":12,"b":11,"c":"abc"}';            
        var json=JSON.parse(str);            
        console.log(json)
    • 2. json 简写
      (1)名字一样:名字和值(key和value)一样的 ,留一个就行;
        let a=12;
        let b=12;
                  
        //var json={"a":a,"b":b,"c":"abc"};
        var json={a,b,c:"abc"};  //简写
        console.log(json)
      (2)方法 :有方法的 “ =function "一块删除。
      var json={
        "a":12,
        /*show:function(){
           alert(this.a)
        }*/
                      
        show(){          //简写
           alert(this.a)   
        }
      }
      json.show();

    8.promise对象 - 消除异步操作

      官方上说是 异步编程的一种解决方案。

      有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

      Promise也有一些缺点:

        首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。

        其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

        第三,当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

     基本用法:

      let p=new Promise(function(resolve,reject){  //Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数
            //异步代码
            //resolve --成功了
            //reject -- 失败了
            //alert(resolve)
            
            $.ajax({        
                url:'data/arr1.txt',                    
                dataType:'json',
                success(arr){
                    resolve(arr)
                },
                error(err){
                    reject(err);
                }
            })
        });
        
        p.then(function(arr){   //then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。
            alert("成功"+arr);
            console.log(arr)
        },function(err){
            console.log(err)
            alert("失败"+err);
        });
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    //封装起来 就是
       function CreatPromise(url){       
           //返回出去
               return new Promise(function(resolve,reject){                     
                $.ajax({        
                    url,                    
                    dataType:'json',
                    success(arr){
                        resolve(arr)
                    },
                    error(err){
                        reject(err);
                    }
                })
            });       
       }
       
        //Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。                                   
        Promise.all([       //Promise.all方法接受一个数组作为参数
            CreatPromise('data/arr.txt'),
            CreatPromise('data/json.txt'),
        ]).then(function(arr){
            let [arr1,arr2]=arr;
            console.log(arr1);
            console.log(arr2);
            //alert(arr1);
            //alert(arr2);
            alert("全成功");      
        },function(err){
            console.log(err);
            alert("至少有一个失败");
        })

    有了jquery 的promise (jquery 已经封装好了promise):

    Promise.all([
        $.ajax({url:'data/arr.txt',dataType:"json"}),                                            
        $.ajax({url:'data/json.txt',dataType:"json"})                    
        ]).then(result=>{            
            let [arr,json]=result;
            alert("成功");
            console.log(arr,json);
    
        },err=>{
            alert("失败");
        })

    9.generator函数

       也是一种异步编程解决方案。

       普通函数--一路到底(飞机、高铁);涉及到异步操作只能用回调的方式。

        generator函数--中间能停(出租车); 可以停,数据什么时候回来在走,适合逻辑性强的。注意不能写成箭头函数。

        promise--也是不是停;有逻辑的情况下很麻烦,适合一次读一堆数据。

     

    第一个generator 函数实例:

    //generator函数
      function *show(){  //多一个星号 可以单独放,可以贴function或者函数名
          alert("a");
          
          yield;   //配合generator函数使用   暂时放弃执行
          
          alert("b");
      }
      
      let genObj=show();   //创建一个generator对象(和普通函数不一样,普通函数直接调用即可)
      alert(genObj);     //Object generator
      console.log(genObj);

    //
    next方法 指向下一个状态
     genObj.next(); //a 

    genObj.next(); //b

    调用遍历器对象的next方法,使得指针移向下一个状态。
    也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield语句(或return语句)为止。
    换言之,Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。

     generator 原理:

     //generator函数
      function *show(){  
          alert("a");
          
          yield;   
          
          alert("b");
      }    
    
      //generator原理是,把大函数切成多个小函数              
      function show_1(){
          alert("a");
      }
       function show_2(){
          alert("b");
      }              
      
      let genObj=show();   
                 
      genObj.next();  //show_1
      genObj.next();  //show_2

      yield 是什么?

      (1)可以传参

    //generator函数
      function *show(){  
          alert("a");
          
          let c=yield;   
          
          alert("b");
          alert(c);  // ——>5
      }            
      
      let genObj=show();   
                 
     //给yield 传参 第一个是没用的,接收的是第二个参数
      genObj.next(12);  
      genObj.next(5);  

    //5

     (2)可以返回

     //generator函数
      function *show(){  
          alert("a");
          
          yield 12;   
          
          alert("b");
          
          return 2;//  最后一步的过程通过return给
                         
      }            
      
      let genObj=show();   
         
      let res1=genObj.next();  //有中间结果的  
       console.log(res1);      // ->{value: 12, done: false}
      let res2=genObj.next();  //有中间结果的
    //console.log(res2);    // 没有return时->{value: undefined, done: true}
      console.log(res2);      // 有return时->{value: 2, done: true}

    yield语句

    由于Generator函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield语句就是暂停标志。

    遍历器对象的next方法的运行逻辑如下。

    (1)遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

    (2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句。

    (3)如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

    (4)如果该函数没有return语句,则返回的对象的value属性值为undefined

    需要注意的是,yield语句后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行,因此等于为JavaScript提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。

     generator 应用

    generatro 搭配 runner 写更加简化。

    runner.js :

    function runner(_gen){
      return new Promise((resolve, reject)=>{
        var gen=_gen();
    
        _next();
        function _next(_last_res){
          var res=gen.next(_last_res);
    
          if(!res.done){
            var obj=res.value;
    
            if(obj.then){
              obj.then((res)=>{
                _next(res);
              }, (err)=>{
                reject(err);
              });
            }else if(typeof obj=='function'){
              if(obj.constructor.toString().startsWith('function GeneratorFunction()')){
                runner(obj).then(res=>_next(res), reject);
              }else{
                _next(obj());
              }
            }else{
              _next(obj);
            }
          }else{
            resolve(res.value);
          }
        }
      });
    }

    generator :

    runner (function *(){
        let data1=yield $.ajax({url:"data/1.txt",dataType:"json"});
        let data2=yield $.ajax({url:"data/2.txt",dataType:"json"});
        let data3=yield $.ajax({url:"data/3.txt",dataType:"json"});
        
        console.log(data1,data2,data3);
    })

    总结:

    2015年6月正式发布的ECMAScript 6.0(简称 ES6)是 JavaScript 语言的下一代标准,它越来越向后台化发展。

    兼容:IE10+、chrome、FireFox、移动端、NodeJs。

    要兼容:(1)提前编译

        (2)在线转换 :引一个browser.js  <scirpt type="text/babel">



      

  • 相关阅读:
    Merge Intervals
    Merge k Sorted Lists
    Sqrt(x)
    First Missing Positive
    Construct Binary Tree from Inorder and Postorder Traversal
    Construct Binary Tree from Preorder and Inorder Traversal
    Distinct Subsequences
    Reverse Nodes in k-Group
    Jump Game II
    Jump Game
  • 原文地址:https://www.cnblogs.com/sun927/p/9429909.html
Copyright © 2020-2023  润新知