中软Day16——ES6概述

中软Day16

ES6

ES6概述

ES6,全称ECMA Script6.0,是 新一代的JS语言标准,发布于15年左右。

目标让js语言成为能支持去编写大型复杂的应用语言, 成为企业级开发语言。

  • ECMAscript和javascript区别:

    ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)。日常场合,这两个词是可以互换的。

变量

  • 变量有什么新特性?
    可以使用let去定义变量,可以使用const去定义常量,解构赋值。

  • let命令作用:用于声明变量,类似于var,但是,它只在let所在的代码块内部有效。

    <script type="text/traceur">
    {
           
        var a=100;
        let b=200;
    }
     
    console.log(a);  //100
    console.log(b);  //Error,b is not defined
     
    </script>
    
  • let与var的区别

    • var

      var a = [];
      for (var i = 0; i < 10; i++) {
               
      a[i] = function () {
               
          console.log(i);
      };
      }
      a[6](); // 10
      /*变量i是var声明的,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的function在运行时,会通过闭包读到这同一个变量i,导致最后输出的是最后一轮的i的值,也就是10。
      
    • let

      var a = [];
      for (let i = 0; i < 10; i++) {
               
        a[i] = function () {
               
          console.log(i);
        };
      }
      a[6](); // 6
      //变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。
      
  • 性质:

    • let具备块级作用域(一是内层变量可能会覆盖外层变量。二是用来计数的循环变量泄露为全局变量。)

    • let声明的变量只能在代码块内部调用

    • 没有变量提升

      • ES5

        <script type="text/traceur">
           //ES5
          console.log("ES5");
          for(var i=0;i<10;i++){
                   
              var c=i;
              a[i]=function(){
                   
                 console.log(c);
              };
          };
          a[5]();  //9
        </script>
        
      • ES6

        //在let声明变量的时候,就不会如此结果
        <script type="text/traceur">
           //ES6
          console.log("ES6");
          for(let j=0;j<10;i++){
                   
              let c=j;
              a[i]=function(){
                   
                 console.log(c);
              };
          };
          a[5]();  //5
        </script>
        

        解析:由于在执行函数时,将j=5作为变量赋值给传入函数中,所以执行完毕即退出。

    • 暂时性死区
      在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区” 。

      //只要块级作用域中存在let命令,所声明的该变量是有效的“绑定的”,不再受外部影响。
      //a在let a声明前就console了,即表示“未定义undefined”,在let之前的区域为“暂时性死区”。
      <script type="text/traceur">
      //var a=100;
      {
               
          console.log(a);    //undefined
          let a=100;
          console.log(a);    //100
      }
      </script>
      
      <!--在该案例中,多了“var a”,但是let所声明的变量,并不在乎外界的影响,所以在let作用域内部,var声明的变量是无效的,即“console.log(a)”还是defined(3let不允许重复声明情况1:模块内部重复声明(不允许用let命令重复声明)>
      <script type="text/traceur">
      var a=100;
      {
               
          console.log(a);    //undefined
          let a=100;
          console.log(a);    //100
      }
      </script>
      
      • 变量作用域不同

        <script type="text/trancer">
        {
                   
           var a=1;
           var a=2;
           console.log(a);  //2
        }
        {
                   
           let  a=2;
           console.log(a);  //2
        }
         
        </script>
        
    • 不允许重复声明
      let不允许在相同作用域内部重复声明同一个变量,所以也是不允许在函数中重新声明参数。

      <script type="text/trancer">
      {
               
         var a=1;
         var a=2;
      }
      console.log(a);  //2
       
       
      {
               
         var b=1;
         let  b=2;
      }
      console.log(b);
       
       
      {
               
         let c=1;
         let c=2;
      }
      console.log(c);
      </script>
      //解析:由于var重复声明的变量是可以运行的,即后边的会覆盖前边的变量。但是,只要声明的变量存在let,则若重复声明一个变量,都会报错。无论有一个let,let在前还是在后;还是有两个重复let声明的变量,都是有错误的。
      

      模块之间不影响,可重复声明

      <script type="text/trancer">
      {
               
         var a=1;
         var a=2;
         console.log(a);  //2
      }
      {
               
         let  a=2;
         console.log(a);  //2
      }
       
      </script>
      

const,var,let三者区别

  1. const定义的变量不可以修改,而且必须初始化。

     const b = 2;//正确
    	 // const b;//错误,必须初始化 
    	console.log('函数外const定义b:' + b);//有输出值
    	// b = 5;
    	// console.log('函数外修改const定义b:' + b);//无法输出 
    
  2. var定义的变量可以修改,如果不初始化会输出undefined,不会报错。

    var a = 1;
    // var a;//不会报错
    console.log('函数外var定义a:' + a);//可以输出a=1
    function change(){
    a = 4;
    console.log('函数内var定义a:' + a);//可以输出a=4
    } 
    change();
    console.log('函数调用后var定义a为函数内部修改值:' + a);//可以输出
    
  3. let是块级作用域,函数内部使用let定义后,对函数外部无影响。

    let c = 3;
    console.log('函数外let定义c:' + c);//输出c=3
    function change(){
    let c = 6;
    console.log('函数内let定义c:' + c);//输出c=6
    } 
    change();
    console.log('函数调用后let定义c不受函数内部定义影响:' + c);//输出c=3
    

块级作用域

  • ES5 VS ES6
    ES5:在ES5中,只有两种作用域:全局作用域 + 局部作用域
    场景1——内部作用域会覆盖外部作用域
    场景2——用于计数的循环变量泄露为全局变量(循环变量结束,变量依然存在,内存占用)

  • ES6

    块级作用域

    //ES6:增加了“块级作用域”的概念
    <script type=”text/traceur”>
    console.log(ES6:”);
     
    let num=100;
    if(true){
           
    	let num=200;
    }
    console.log(num);   //100
    </script>
    
    <script type=”text/traceur”>
    function fun(){
           console.log(I am outside!);}
    (function(){
           
    	if(false){
           
    		function fun(){
           
    			console.log(I am inside!);
    		};
    	};
    	fun();	//I am outside!
    })();
    
  • ES5

    <script type=”text/javascript”>
    console.log(ES5);
     
    var num=100;
    if(true){
           
    	var num=200;
    }
    console.log(num);   //200
    </script>
    

    立即执行函数

    <script type=”text/javascript”>
    function fun(){
           
       Console.log(I am outside!);
    }
     
    (function(){
           
    	if(false){
           
    		function fun(){
           
      			console.log(I am inside!);
    		};
    	};
     
    	fun();	//I am inside!
    })();
    </script>
    
    • do表达式

      本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。

      {
        let t = f();
        t = t * t + 1;
      }
      

      块级作用域将两个语句封装在一起。但是,在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量。

      • do表达式可以返回值

        let x = do {
          let t = f();
          t * t + 1;
        };
        //变量x会得到整个块级作用域的返回值。
        

常量

const一旦声明变量,就必须立即初始化,不能留到以后赋值。 因为以后再没法赋值了,所有声明的时候一定有值 。
只在声明所在的块级作用域内有效
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
用途:为了防止意外修改变量
比如:引入库名,组件库

  • Const也是声明变量,但是它声明的是一个常量。一旦声明,就不能改变。

    <script type=”text/traceur”>
      const Pi =3.1415926;
      console.log(Pi);
      Pi=3;
      console.log(Pi);	//Pi is read-only——Error
    </script>
    
  • 使用const命令

    <script type=”text/traceur”>
      const Pi =3.1415926;
      console.log(Pi);
      Pi=3;
      console.log(Pi);	//Pi is read-only——Error
    </script>
    
  • const块级作用域

    <script type=”text/traceur”>
    if(true){
            
      const Pi=3.1415926;  
    }
    console.log(Pi);	//	Pi is not defined!——error
    </script>
    
  • const对象

    <script type=”text/traceur”>
    	const person={
           };
         	person.name=”Zhangsan”;
    	person.age=30;
     
    	console.log(person.name);
    	console.log(person.age);
    	console.log(person) ;   //object{name:  age}
    </script>
    
  • const数组

    <script type=”text/traceur”>
    	const arr=[];
    	console.log(arr);
    	console.log(arr.length);
    	console.log(------);
    	arr.push(“Hello world!);
    	console.log(arr);
    	console.log(arr.length);
     
    	arr.length=0;
    	console.log(arr.length);
     
    	//错误用法
    	arr = [“Hello world”];
    </script>
    
  • const对象冻结

    <script type=”text/traceur”>
    	const person = Object.freeze({
           
    		name = “Zhangsan”;
    		age=12;
    	});  //冻结对象;
    	console.log(person.name);   //Zhangsan
    	console.log(person.age);     //12
    	console.log(person);        //Object
    </script>
    
    • 彻底冻结对象

      var constantize=(obj) => {
               
      	object.freeze(obj);
      	object.keys(obj).forEach(key , value) => {
               
      		if( typeof obj[key] === ‘object’ ){
               
      			constantize( obj[key] );
      		};
      	};
      };
      

    用处:用于解决异步数据获取时数据向外传递,例如ajax获取的数据向外传递

    • catch:用来捕获错误
    • all: 全部,用于将多个promise对象,组合,包装成一个全新的promise实例。
      Promise.aa([p1,p2,p3]);
      所有的promise对象,都正确,才走成功
      否则,只要有一个错误,是失败了
    • race —返回也是一个promise对象
      最先能执行的promise结果,那个最快,用哪个。

跨模块常量

<script type=”text/traceur”>
// module1.js
export const intVariantName =100;
export const floatVariantName =3.14;
export const charVariantName =”variantValue”;
 
// user.js
import * as  var from./module’;
console.log(variant.IntvariantName);      // 100
console.log(variant.floatvariantName);     //3.14
console.log(variant.charvariantName);     //”variantValue”
 
//otherUser.js
import{
     intVariantName,floatVariantName } as variant  from./module’;
console.log(variant.IntvariantName);      // 100
console.log(variant.floatvariantName);     //3.14
</script>

字符串

字符串链接

let obj = {
     f:'first',l:'last'};
var box = document.getElementById('box');
console.log(box);
var str = `
    
  • ${ obj.f}
  • ${ obj.l}
`
; console.log(str); box.innerHTML=str;

字符串遍历

字符串的遍历:
    for(let str of 'abc'){
     
        console.log(str);
    }   
CharAt()方法:
    'abc'.charAt(2)
  • 方法

    JavaScript只有 indexOf 方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。

    • includes():返回布尔值,表示是否找到了参数字符串。
    • startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
    • endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。

解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

var [a,b,c] = [12,4,5]; 
var {
     a,b,c} = {
     a:23,b:4,c:33} 跟顺序无关 
模式匹配: 左侧和右侧模式必须一样 
var [a,[b,c],c] = [2,[2,3],4]; 
var [a,b,{
     a,b}] = [2,3,{
     ‘aa’,’bb’}]
//通常情况下
var first = someArray[0];
var second = someArray[1];
var third = someArray[2];

//解构赋值
let [first, second, third] = someArray; //比上面简洁多了吧

//还有下面例子
let [,,third] = [1,2,3];
console.log(third); //3

let [first,...last] = [1,2,3];
console.log(last); //[2,3]

//对象解构
let {
     name,age} = {
     name: "lisi", age: "20"};
console.log(name); //lisi
console.log(age); //20

//注意
let {
     ept1} = {
     };
console.log(ept1); //undefined
let {
     ept2} = {
     undefined};
console.log(ept2); //undefined
let {
     ept3} = {
     null};
console.log(ept3); //null
  • 数组的解构赋值

    let [a,b,c] = [1,2,3];
    console.log(a+b+c);  //6
    
    let [foo,[[bar]],baz] = [1,[[2]],3];
    console.log(a+b+c); //6
    
    let [ , ,third] = ["foo","bar","baz"];
    console.log(third);  //baz
    
    let [head, ...tail] = [1,2,3,4];
    console.log(tail);  //[ 2, 3, 4 ]
    
    let [x,y,...z] = ['a'];
    console.log(x); //a
    console.log(y); //undefined
    console.log(z); //[]
    
    以下情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组
    let [aaa,bbb] = [1];
    console.log(aaa); //1
    

    注: 如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。
    事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。

    • 案例

      数组对应位置

      let [one, ,three] =[“one”,”two”,”three”];
      console.log(one);	//one
      console.log(three);  //three
       
      let [head,...tail] =[0,1,2,3,4,5];
      console.log(head);   //0
      console.log(tail);	//[1,2,3,4,5]
      

      不完全解构

      定义:等号左边的模式,只匹配一部分的等号右边的数据。(不会出现溢出等现象)

      <script type=”text/traceur”>
      let [x,y] = [1,2,3];
      console.log(x);	//1
      console.log(y);  	//2
       
      let [a,[b],c] = [1,[2,3],4];
      console.log(a);	//1
      console.log(b);	//2
      console.log(c);	//4
       
      let [a,[b,d],c] =[1,[2,3],4];
      console.log(a);	//1
      console.log(b);	//2
      console.log(d);	//3
      </script>
      
  • 默认值

    解构赋值允许默认值。

    let [foo = true] = [];
    foo // true
    
    let [x, y = 'b'] = ['a']; // x='a', y='b'
    let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
    注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。
    
    • 案例

      指定默认值

      <script type=”text/traceur”>
      var [temp=”string”] = [];
      console.log(temp);     //string
       
      var [temp=”string” ]= [“tempString”];
      console.log(temp);	//tempString
       
      var [x=”aaa”,y] = [“bbb”];
      console.log(x);	//bbb
      console.log(y);	//undefined
       
      var [m,n=”aaa”] = [“bbb”];
      console.log(m);	//bbb
      console.log(n);	//aaa
       
      var [p,q=”aaa”] = [“bbb”,undefined];
      console.log(p);	//bbb
      console.log(q);	//aaa(由于undefined是未定义,所以有值即输出)
      </script>
      //非遍历数组解构产生报错
      
  • 对象的解构赋值

    对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    案例:
    
    let {
           bar,foo} = {
           foo:"aaa",bar:"bbb"};
    console.log(bar+foo);   //bbbaaa
    
    let {
           bar:b,foo:f} = {
           foo:"aaa",bar:"bbb"};
    console.log(b+f);   //bbbaaa
    
    let obj = {
           
        p: ['hello',{
           y:'world'}]
    }
    let {
           p:[x,{
           y}]} = obj;
    console.log(x+y);   //helloworld
    
    const node = {
           
        loc: {
           
            start: {
           
                line: 1,
                column: 5
            }
        }
    }
    let {
           loc,loc:{
           start},loc:{
           start:{
           line}}} = node;
    // line // 1
    // loc  // Object {start: Object}
    // start // Object {line: 1, column: 5}
    
    let obj2 = {
           };
    let arr2 = [];
    ({
           foo2:obj2.pro,bar2:arr2[0]}={
           foo2:123,bar2:456});
    console.log(obj2,arr2);
    

    对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

    • 属性名与变量名
      由于变量名与属性名并不一致,所以需要如下方式来改变,以实现如上的效果。

      <script type=”text/traceur”>
      var{
               name:person_name,age:person_age,id:person_id}={
               id:007,age:23,name:”zhangsan”};
      console.log(person_name);	//zhangsa
      console.log(person_age);	//23
      console.log(person.id);	//007
      </script>
      
    • 对象解构指定默认值生效条件

      默认值生效的条件是,对象的属性值严格等于undefined。

      <script type=”text/traceur”>
      var {
               a=3} =	{
               a= undefined};
      console.log(a);	//3
       
      var {
               b=3} = {
                b=null };
      console.log(b);	// null
      </script>
      
    • 现有对象的方法

      <script type=”text/traceur”>
      console.log(Math.PI/6);
       
      let {
               sin,cos,tan} = Math;
      console.log(sin(Math.PI/6));   
      </script>
      
  • 字符串的解构赋值

    字符串被转换为一个类似数组的对象。
    属性的解构赋值:由于字符串属性length,可以利用该属性进行解构赋值。

    const [a,b,c,d,e] = "hello";
    console.log(a,b,c,d,e); //hello
    let {
           length:len} = "hello";
    console.log(len); //5
    
  • 数值和布尔值的解构赋值

    解构赋值时,如果等号右边是数值和布尔值,则会先转为对象

    注:解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

  • 函数参数的解构赋值

    <script type=”text/traceur”>
    function fun( {
           x=0,y=0} = {
           } ){
           
    	return [x,y];
    };
     
    console.log(fun( {
           x:100,y:200} ) );  //[100,200]
    console.log(fun({
           x:100}));	    //[100,0]
    console.log(fun({
           }));	 //[0,0]
    </script>
    
  • 解构赋值的用途

    • 交换变量的值

      <script type="text/traceur">
         //ES5
         console.log("ES5:");
         var a=100;
         var b=200;
         console.log("交换前:");
         console.log("a="+a);  //100
         console.log("b="+b);  //200
         var temp;
         temp=a;
         a=b;
         b=temp;
         console.log("交换后:");
         console.log("a="+a);   //200
         console.log("b="+b);   //100
       
       
         //ES6
         console.log("ES6:");
         var x,y;
         console.log("交换前:");
         console.log("a="+a);  //100
         console.log("b="+b);  //200
       
         //利用数组解构的方法进行交换
         [x,y] = [y,x];
         console.log("交换后:");
         console.log("a="+a);  //200
         console.log("b="+b);  //100
      </script>
      
    • 从函数中返回值

      • 返回数组

        <script type="text/traceur">
           function fun(){
                   
               return [1,2,3];
           };
         
          var [x,y,z] = fun();
          console.log(x);   //1
          console.log(y);   //2
          console.log(z);   //3
        </script>
        
      • 返回对象

        <script type="text/traceur">
           function fun(){
                   
              return {
                   
                 id:"007",
                 name:"zhao",
                 age:20
              };
          };
         
          var {
                   id,name,age} = fun();
          console.log(id);
          console.log(name);
          console.log(age);
         
          var {
                   id:person_id,name:person_name,age:person_age} = fun();
          console.log(person_id);
          console.log(person_name);
          console.log(person_age);
        </script>
        
    • 函数参数定义

      function fun(id,name,age){
               
       
      };
       
      fun({
               id:"007",name:"zhao",age:20});
       
      //参数是一组无次序的值
      function fun({
               x,y,z}){
               
       
      };
      fun({
               x:100,y:200,z:300});
      
    • 函数参数默认值

      <script type="text/traceur">
         jQuery.ajax =function(url,{
               
      	async = true,
              beforeSend = function(){
               },
              cache = true,
              global = true,
         }){
               
      	//
         };
      </script>
      
    • 遍历Map结构

      <script type="text/traceur">
      	var map =new Map();
      	map.set("id","007");
      	map.set("name","Zhao");
       
      	console.log(map);		//Map{id => "007",name =>"Zhao"}
      	console.log(typeOf(map));	//Object
      	
       	for(let [key,value] of map){
               
      		console.log(key+"is" + value);
      	}
      	// id is 007
      	// name is Zhao
       
              //获取键名
      	for(let[key] of map){
               
      		console.log(key);	
      	} 
      	// id
      	// name
       
      	//获取键值
      	for(let[,value] of map){
               
      		console.log(value);
      	}
              // 007
      	// Zhao
      </script>
      
    • 提取JSON数据

      <script type="text/traceur">
        var jsonData ={
               
           id:"007",
           name:"zhao",
           age:20,
           score:[100,90,89]
        };
       
        console.log(jsonData);
       
        console.log("ES5");
        console.log("Name"+jsonData.name);
        console.log("age"+jsonData.age);
        console.log("Chinese score"+jsonData.score[0]);
        console.log("Math score"+jsonData.score);
       
       console.log("ES6");
       let{
                id:number, name,age,score.score } =jsonData;
        console.log(number);
        console.log(name);
        console.log(age);
        conosle.log(score.Chinese);
      </script>
      

复制数组

(1).var arr = [2,3,4,5];
    var arr2 = Array.from(arr);
(2). var arr = [2,3,4,5];
        var arr2 = [];
        for(var i = 0 ; i < arr.length ; i++){
     
            arr2[i]=arr[i]
        }
(3). var arr2 = [...arr];
案例:
    function show(...args){
     
    console.log(...args);
    }
    show(1,2,3,4);

箭头函数

ES6中可以使用 => 作为函数表达形式,极简风格,参数+ => +函数体。

var foo = function(){
     return 1;};
//等价于
let foo = () => 1;
let nums = [1,2,3,5,10];
let fives = [];

nums.forEach(v => {
     
  if (v % 5 === 0)
    fives.push(v);
});

console.log(fives); //[5,10]
//箭头函数中的 this 指的不是window,是对象本身。
//arguments不能使用this
const full = ({
     first,last}) => first + ' ' + last;

//等同于
function full(person){
     
   return person.first + ' ' + person.last;
}
//箭头函数可以与变量解构结合使用。
  • 注意点:

    • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

    • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

    • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

    • 不可以使用yield命令,因此箭头函数不能用作Generator函数。

  • 箭头函数this指向问题
    箭头函数里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。

    this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

对象

对象语法简洁化

var name = 'a';
var age = 122;
var person = {
     
    name,
    age,
    showName(){
     
        return this.name;
    },
    showAge(){
     
        return this.age;
    }
}
面向对象:

Es5:

function Person(name,age){
      //类,构造函数
    this.name = name;
    this.age = age;
}
Person.prototype.showName = function(){
     
    return this.name;
}
Person.prototype.showAge = function(){
     
    return this.age;
}
var p1 = new Person('aaa',23);
console.log(p1.showName());

es6:

类: class

构造函数:  constructor 生成完实例以后,自己就执行的
class Person{
     
    constructor(name='default',age=0){
      函数的默认值
        this.name = name ;
        this.age = age;
    }
    showName(){
     
        return this.name;
    }
    showAge(){
     
        return this.age;
    }
}
var p = new Person('aaa',12);
console.log(p.showName());
继承:

Es5:

子类.prototype = new 父类();

Es6:

class Worker extends Person{
     }
var w1 = new Worker('mmm',232);
console.log(w1.showAge());

class Worker extends Person{
     
    constructor(name,age,job='扫地的'){
     
        super(); //调用父级的构造
        this.job = job;
    }
    showJob(){
     
        return this.job;
    }
}
var w1 = new Worker('mmm',232);
console.log(w1.showAge());
console.log(w1.showJob());
  • 循环遍历整个对象

    var arr = ['aa','bb','dd'];
    
    for(var i in arr){
           
        console.log(arr[i]);
    }  //for in 循环数组,i为下标
    
    for(var i of arr){
           
        console.log(i);
    }   //for of 循环数组,i为值
    
    var json = {
           'a':'apple','b':'banan','o':'orange'};
    
    for(var i in json){
           
        console.log(json[i]);
    } // for in 循环数组,数组为键,但不能用for of 循环json
    

全局对象

全局对象:最顶层对象。

  • 浏览器环境——window对象;
  • Node.js——global对象
  • Javascript——所有全局变量都是全局对象的属性

ES6中规定:

属于全局对象的属性:var、function声明的全局对象

不属于全局对象属性:let、const、class命令声明的全局对象

  • 全局对象的属性

    <script type=”text/traceur”>
    var varName =”varValue”;
    //浏览器环境
    console.log(window.varName);	//varValue
    //node.js环境
    console.log(global.varName);       //varValue
    //通用环境
    console.log(this.varName);         //varValue
     
    let letName =”letValue”;
    console.log(window.letName);	//letValue   ||  undefined—use strict
    console.log(this.letName);	//letValue   ||  undefined—use strict
    </script>
    

模块化

必须引入traceur和bootstrap,type必须写成module

ES6自带模块化

如何定义(导出)模块
    const a = 12;
    export default a;
    const b = 12;
    export default {a,b}

如何使用(引用)
    Import modA from ‘./a.js’

Promise(承诺)

三种状态:

pendingz(等待、处理中)——》Resolve(完成)
                          ——》Rejected(拒绝、失败)

var p1 = new Promise(function(resolve,reject){
     
    //resolve 成功了
    //reject 失败了
});

var p1 = new Promise(function(resolve,reject){
     
    if(异步处理成功了){
     
    resolve(成功的数据)
}else{
     
        reject(失败的原因)
}
});
p1.then(成功(resolve),失败(reject))

Symbol

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

案例:
let s1 = Symbol();
let s2 = Symbol();
console.log(s1 === s2);  //false

let s11 = Symbol('aaa');
let s22 = Symbol('bbb');
console.log(s11 === s22);   //false

数值扩展(Number)

  • Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity。

    Number.isFinite(15); // true
    Number.isFinite(0.8); // true
    Number.isFinite(NaN); // false
    Number.isFinite(Infinity); // false
    Number.isFinite(-Infinity); // false
    Number.isFinite('foo'); // false
    Number.isFinite('15'); // false
    Number.isFinite(true); // false
    
  • Number.isNaN()用来检查一个值是否为NaN。

    Number.isNaN(NaN) // true
    Number.isNaN(15) // false
    Number.isNaN('15') // false
    Number.isNaN(true) // false
    Number.isNaN(9/NaN) // true
    Number.isNaN('true'/0) // true
    Number.isNaN('true'/'true') // true
    
  • 新方法与传统全局方法区别

    它们与传统的全局方法isFinite()和isNaN()的区别在于:

    • 传统方法先调用Number()将非数值的值转为数值,再进行判断
    • 这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。
    isFinite(25) // true
    isFinite("25") // true
    Number.isFinite(25) // true
    Number.isFinite("25") // false
    
    isNaN(NaN) // true
    isNaN("NaN") // true
    Number.isNaN(NaN) // true
    Number.isNaN("NaN") // false
    Number.isNaN(1) // false
    
  • Number.parseInt(), Number.parseFloat()

    ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。

    // ES5的写法
    parseInt('12.34') // 12
    parseFloat('123.45#') // 123.45
    
    // ES6的写法
    Number.parseInt('12.34') // 12
    Number.parseFloat('123.45#') // 123.45
    

    这样做的目的,是逐步减少全局性方法,使得语言逐步模块化。

    Number.parseInt === parseInt // true
    Number.parseFloat === parseFloat // true
    
  • Number.isInteger()用来判断一个数值是否为整数。

    Number.isInteger(25) // true
    Number.isInteger(25.0) // true
    Number.isInteger(25.1) // false
    Number.isInteger("15") // false
    Number.isInteger(true) // false
    
  • Number.EPSILON

    ES6在Number对象上面,新增一个极小的常量Number.EPSILON。

    Number.EPSILON
    // 2.220446049250313e-16
    Number.EPSILON.toFixed(20)
    // '0.00000000000000022204'
    

Math对象扩展

  • Math.trunc方法用于去除一个数的小数部分,返回整数部分。

    Math.trunc(4.1) // 4
    Math.trunc(4.9) // 4
    Math.trunc(-4.1) // -4
    Math.trunc(-4.9) // -4
    Math.trunc(-0.1234) // -0
    

    对于非数值,Math.trunc内部使用Number方法将其先转为数值。

    Math.trunc('123.456')
    // 123
    

    对于空值和无法截取整数的值,返回NaN。

    Math.trunc(NaN);      // NaN
    Math.trunc('foo');    // NaN
    Math.trunc();         // NaN
    
  • Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

    Math.sign(-5) // -1
    Math.sign(5) // +1
    Math.sign(0) // +0
    Math.sign(-0) // -0
    Math.sign(NaN) // NaN
    Math.sign('foo'); // NaN
    Math.sign(); // NaN
    
  • Math.imul方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。

    Math.imul(2, 4)   // 8
    Math.imul(-1, 8)  // -8
    Math.imul(-2, -2) // 4
    
  • Math.fround方法返回一个数的单精度浮点数形式。

    Math.fround(0)     // 0
    Math.fround(1)     // 1
    Math.fround(1.337) // 1.3370000123977661
    Math.fround(1.5)   // 1.5
    Math.fround(NaN)   // NaN
    

数据结构(Set)

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set 本身是一个构造函数,用来生成 Set 数据结构。

const s = new Set();
[2,3,4,4,6,7].forEach(x => s.add(x));

for(let i of s){
     
    console.log(i);
}

const set = new Set([2,3,4,4,6,7]);
console.log(...set);
console.log(set.size);

数组去重:

展示了一种去除数组重复成员的方法。
[...new Set(array)]
const items = new Set([1,2,3,4,5,5]);
const array = Array.from(items);
console.log(items);
console.log(array);
  • Set的属性:
    set.size,返回Set实例的成员总数。
    Set的方法:Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。

    • add(value):添加某个值,返回 Set 结构本身。
    • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
    • has(value):返回一个布尔值,表示该值是否为Set的成员。
    • clear():清除所有成员,没有返回值。
  • Set的遍历操作:

    • keys():返回键名的遍历器
    • values():返回键值的遍历器
    • entries():返回键值对的遍历器
    • forEach():使用回调函数遍历每个成员
    let set = new Set(['red','green','blue']);
    for(let item of set.keys()){
           
        console.log(item);
    }
    for(let item of set.values()){
           
        console.log(item);
    }
    for(let item of set.entries()){
           
        console.log(item);
    }
    set.forEach(x => console.log(x));
    
    let arr = [...set];
    console.log(arr);
    
    

Map

JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。

  • map和object比较
    Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应。

    var map = new Map();
    
    map.set('a','apple'); //设置值
    map.set('b','banana');
    map.set('o','orange');
    
    console.log(map);
    console.log(map.get('a')); //获取值
    console.log(map.get('b'));
    
    map.delete('a');  //删除
    console.log(map);
    
    //遍历map
    for(var name of map){
           
        console.log(name);      //键值
    }
    
    for(var [key,value] of map){
           
        console.log(key,value);  //键和值
    }
    
    for(var name of map.entries()){
            //默认
    
    }
    
    for(var key of map.keys()){
           
        console.log(key);       //只循环键
    }
    
    for(var value of map.values()){
           
        console.log(value);     //只循环值
    }
    
    for of 也可循环数组,但不能单独循环值
    
    
  • Map实例属性

    • size 属性 size属性返回 Map 结构的成员总数
    • set(key, value) set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经 有值,则键值会被更新,否则就新生成该键。
    • get(key) get方法读取key对应的键值,如果找不到key,返回undefined。
    • has(key) has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
    • delete(key) delete方法删除某个键,返回true。如果删除失败,返回false。
    • clear()clear方法清除 所有成员,没有返回值。
  • 遍历方法 §
    Map 结构原生提供三个遍历器生成函数和一个遍历方法。

    • keys():返回键名的遍历器
    • values():返回键值的遍历器
    • entries():返回所 有成员的遍历器
    • forEach():遍历 Map 的所有成员
    const map = new Map([
        ['f','no'],
        ['t','yes']
    ]);
    for(let key of map.keys()){
           
        console.log(key);
    }
    for(let value of map.values()){
           
        console.log(value);
    }
    for(let item of map.entries()){
           
        console.log(item);
    }
    map.forEach(item => console.log(item));
    
    

全局对象属性

全局对象:最顶层对象。

  • 浏览器环境——window对象;
  • Node.js——global对象
  • Javascript——所有全局变量都是全局对象的属性

ES6中规定:
属于全局对象的属性:var、function声明的全局对象
不属于全局对象属性:let、const、class命令声明的全局对象

顶层对象

ES5中顶层对象是window,顶层对象的属性与全局变量是等价的
ES6规定,var 和 function 命令是全局变量,依旧是顶层对象的属性,但是let和const,class命令的全局变量不属于顶层对象的属性,也就是说es6开始,全局变量逐渐与顶层对象的属性脱钩

附录

ctrl+shift+方向键 使代码跳到上下行

你可能感兴趣的:(中软学习笔记,ES6)