• ECMAScript6入门学习--第一天


      ECMAScript与javascript的关系

       ECMA是是一个国际标准化的一个组织,规定了浏览器脚本的语言标准,在上个实际,javascript公司Netscape把javascript托付给ECMA,让其为javascript设置标准,经常见到到版本ES5就是在ES6的上一代标准。

      let

         什么是let?

       狭义理解let是更完美的var,也就是说 他是用来声明变量,方法与var类似,但是优于var,那它的优点是什么呢,下面将详述

       let声明的变量只在该变量的代码块中有效
    {
       var a = 1;
       let b = 2 ;       
    }  
    console.log(a);   //1
    console.log(b);  //undefined
       var声名的变量是全局有效的,输出的值是全局变量 
    for (var i= 0;i<5;i++){
                //do something
            }
    console.log(i) //5

       此时i随着变量提升,已经变成一个全局变量,此时i的值是5

            for (let i= 0;i<5;i++){
                //do something
            }
            console.log(i) //undefined

       如果用let 显示i的值是 undefined 

       下面的两个例子就更加清楚的说明了let声明的变量和var声明的变量的区别了

            var a=[];
            for( var i=0 ;i<5;i++){
                 a[i]=function (){
                    console.log(i)
                }
            }
            console.log(a[4]())  //5
            var a=[];
            for( let i=0 ;i<5;i++){
                a[i]=function (){
                    console.log(i)
                }
            }
            console.log(a[4]()) //4

       var 声明的i是全局变量,循环因子一直是i,只是每次循环i的值发生改变,当访问i时,访问的是全局变量i,所以值就是5

       而let声明的变量是局部变量,每一次循环都要重新声明i,导致当你传入i的时,返回的值就是当前i,所以值就是4

        暂时性死区

         let有一个语法要求,就是let声明之前不能使用var声明变量,否则会产生语法错误

          

       暂时性死区(TDZ:temporal dead zone),在下述代码中就是在let声明命令之前都是变量的死区

            //TDZ起始点
            var tmp = 21;
            //dosomething
            let tmp = 22
    //TDZ结束点


       还有一些不易发现的TDZ
            function tdz( x=y,y=2){
                       //dosomething       
            }
            tdz()        //error y undefined
    
            function tdz( x=2,y=x){
                       //dosomething       
                }
            tdz()   //success
        

         在第一个例子中 ,此时y还没有声明,y就是一个暂时性死区,而在第二个例子中x已经声明了,当第二个形参的值等于已经声明的值,所以不存在暂时性死区 

       let不允许重复声明

        

       let是不允许重复声明一个变量的,但var是可以的,可以这样理解,var声明变量存在变量提升的效果与功能,但是let是不存在变量提升的,这点是let声明变量的特色之一,声明参数必须要咋局部环境中声明,写JS都知道,一是要减少DOM操作,二是不要过多使用全局变量,污染环境。

        块级作用域

         外层代码不受内层代码的影响,有了块级作用域,就不用使用立即执行函数,让外层代码不受内层代码的影响

            function fn(){
                var a = 10;
                {
                    var a=20;
                }
                console.log(a);
            }
            fn() //20
            function fn(){
                var a = 10;
                {
                    let a=20;
                }
                console.log(a);
            }
            fn() //10

        显然let的块级作用域,在函数内部的一个局部作用域中用let声明一个变量,这个局部作用域声明的变量不影响函数内部的变量,当然块级作用域是允许多层嵌套的  

      const

       const是一个只读常量,一旦声明就不能再次声明,常量的值不会再改变

    const c=1;
    var  c= 2 
    //error

           const与let命令相同,只在声明的块级作用域有效,const也不能重复声明

        const本质上,const声明的变量不是值不能改变,而是变量所指的内存地址不能改动,变量是指向一段地址,这个地址有一个变量,并且这个变量存在一个值

          ES6声明变量的方法

        var let const import class 

           变量的解构

        从数组和对象中提取值,对变量进行赋值,这被称为解构

       数组的解构

            let [a1,b1,c1]=[1,2,3];
            console.log(a1); //1
            console.log(b1); //2
            console.log(c1); //3

            对象的解构

            let {a2,b2,c2}={a2:123,b2:456,c3:789}
            console.log(a2);  //123
            console.log(b2);  //456
            console.log(c2);  //789

         嵌套解构

            var obj={
                p:[
                    {per1:123},
                    {per2:456}
                ]
            }
            let {p:[{per1},{per2}]}=obj;
            console.log(per1);  //123
            console.log(per2);  //456

         字符串解构

            const [a,b,c] = "123";
            console.log(a)  //1
            console.log(b)  //2
            console.log(c)  //3

        扩展方法

         把类数组对象转成数组

      [].slice.call()  

        silce(start,end) 

        start:数组片段开始处的数组下标。

        end:数组片段结束处的数组下标。

        ES5使用的是[].slice.call() 将类数组转成真正的数组 

        而ES6给了一个语法糖,仅仅使用Array.from()就可以将类数组转成数组

            let obj2 ={
                "0" : "123",
                "1" : "456",
                length:2
            }
            var _a=Array.from(obj2)
                var _b=[].slice.call(obj2)
            console.log(_a)   //["123","456"]
                console.log(_b)   //["123","456"]
      Array.of 是将一组值转换成数组,比较简单
    let arr = Array.of(1,2,3)
    console.log(arr) //[1,2,3]
        copyWithin方法,在数组内部,将数组成员复制到其他位置处

        copyWithin(target,start,end);

        target:替换数组的位置处

        start:从该位置读取数组。

        end:该位置前(不包括该位置)停止读取数组的位置处

    let newarr = [1,2,3,4,5].copyWithin(0,1,2)
    console.log(newarr ); //[2,2,3,4,5]
         find()找到首次符合条件的数组成员

         array.find(function (){return })

        let result1 = [1,2,3,4,5].find(function (x){return (x%2)===0})  //方法1
        let result2 = [1,2,3,4,5].find(x => (x%2)===0)  //方法2
        console.log(result1);  //2
        console.log(result2);   //2

          方法1和方法2是等价的,find方法和高阶函数map和filter一样回调函数返回的结果都是return 为true时

          entires() keys() values() 遍历返回 entires返回的是键-值 keys是键 values返回的是值

        for (let x of [1,2,3].keys()){
            console.log(x);   // 0 1 2 
        }
    
        for (let x of [1,2,3].entries()){
            console.log(x);  // 1,2,3
        }
             for (let x of [1,2,3].values()){
             console.log(x); [key,value]->[0,1] [1,2] [2,3]
         } 
           箭头函数

           箭头函数有一个最大的特点,就是解决了this的指向问题,this一般指向的是当前对象,但是箭头函数声明了一个变量_this=this,也就是指向函数定义生效时所在的对象

           ES6允许 =>定义函数

        var fn = v =>v 等价于

        var fn=function (v){return v;}

            箭头函数的this对象,就是在定义时所在的对象,而不是使用的时候所在的对象

         function Foo(){
             this.v1=0;
             this.v2=0;
             setInterval(()=> this.v1++,1000);
             setInterval(function (){this.v2++},1000);
         }
          var foo = new Foo();
            setTimeout(() => console.log(foo.v1),3000);  //3
            setTimeout(() => console.log(foo.v2),3000);  //0

        第一个定时器用的是箭头函数,当前定义所在的对象是构造函数,而第二个定时器当前定义所在的对象是this所指的作用域,所以结果是不更新的,永远是0

             Object.assign用于对象的合并
    var obj1={a:1}
    var obj2={b:2}
    var obj3={c:3}
    Object.assign(obj1,obj2,obj3)
    console.log(obj1) //{a:1,b:2,c:3}

        set

         set解构不会添加重复的值

          var s =new Set()
    
      //let newarr =new Set([array])
    
       array.forEach( x=>s.add(x));
    
        for(let x of s){
    
        console.log(x);
    
      }

       set下面有4个常用方法

         add()     

       delete()  (返回值bool)

         has  (返回值bool)

       clear

    let s = new Set();
    s.add(1).add(2).add(3)

       Set可用于数组去重

    [...new Set(array)]
    
    Array.from(new Set(array));

        ...是一个扩展运算符,将一个数组转为以“,”分隔的参数序列  

     map

       map数据组构是键值对的集合,这个键可以是字符串

     map数组组构也有set get has 三个常用的方法

         var set1=new Map();
         var str={p:'123'};
         set1.set(str,"123");
         set1.get(str);
         console.log(set1);// Map(1) {Object {p: "123"} => "123"}

     结果是一个key-value的键值对,键是一个json对象,也可以是字符串

        下面是一个将map数据组构转成json的一个事例

        function maptoobj(permate){
            var obj= Object.create(null);
            for([key,value] of permate){
                obj[key]=value;
            }
            return obj;
        }
        function objtojson(permate){
            return JSON.stringify(maptoobj(permate));
        }
        var mo =new Map().set("1","2").set("2","3");
        console.log(objtojson(mo));  //{"1":"2","2":"3"}

        首先要建一个map mo ,将mo先要抓成对象,也就是 maptoobj函数,再将转成的对象JSON.stringify成字符串,也就是 objtojson函数

           将json数据转成map

           根据将map数据组构转成json的思想,逆向思考,给的是json字符串,先将其json.parse 将parse的结果在解析成map,是不是又要传到一个函数里面,这个函数的功能就是将对象解析成map,是不是又要使用map的set方法了?其中是不是用到for of语句

            function jsontomap(permate){
                var m = new Map()
                for(let x of Object.keys(permate)){
                    m.set(x,permate[x])
                }
                return m ;
            }
            function fn(permate){
                return jsontomap(JSON.parse(permate));
            }
            console.log(JSON.parse('{"1":"2","2":"3"}'))
            console.log(obj[2]);
            console.log(fn('{"name":"2","sex":"3"}'))

        这里面补充一下 obeject.key与object[key]有什么区别

        有时候我们在写一个对象的时候

            var obj={
                "name":"1",
                "time":"2"
            }
            console.log(obj.time); //1
            console.log(obj.name);  //2
    
            var _obj={
                "1":"1",
                "2":"2"
            }
            console.log(_obj[1]); //1
            console.log(_obj[2]);  //2

        但是什么时候用这两个,根据网上查资料,object.key的方法是在没有使用for循环或者遍历,如果为for循环,涉及到依次遍历,则就需使用object[key]了

        就像上面的例子

    for(let  x of Object.keys(permate)){
         m.set(x,permate[x])      
    }

        具体的也可以参考一下  obeject.key与object[key]有什么区别 

        

      学习总结

       这就是我学习ES6总结的一些知识点,写的不好,望轻喷~~

      

      

  • 相关阅读:
    奇虎董事长周鸿祎:谁说没钱不能创业
    分析.NET基础库源码,学习Stream类及相关类
    Why need two IF in singleton pattern in the multiple threads scenario
    It's bad design that leveraging singleton design pattern in db connection
    Asp.net mvc 3 JSONResult return array
    System.Web.HttpContext.Current vs. ControllerContext.HttpContext (almost the same)
    Nhibernate HQL example paging and avoid sql injection
    Asp.net mvc 3 JSON complext object mapping
    Nhibernate configuration in app.config with log4net enabled 0 of 4
    Setup and run a simple nhibernate example
  • 原文地址:https://www.cnblogs.com/dirkhe/p/6935732.html
Copyright © 2020-2023  润新知