es五、es六、es7知識點的概括與總結(筆記)

es五、es6

1.super

  1. super關鍵字使得子類調用了父類中的構造函數,父類可使用子類傳進來的屬性進行各類運算,
  2. super 關鍵字 還能夠調用父類的方法
class Father{
    constructor(x,y){
         this.x=x;
         this.y=y;
     }
     
    sum(){
         console.log(this.x+this.y)  
       }
  
    say(){
         return "我是爸爸" 
      }
  }
 
  class Son extends Father{
    constructor(x,y){
       //調用了父類中的構造函數   
        super(x,y)
       //子類獨有的屬性
        this.x=x;
        this.y=y
      }
      
    say(){
       console.log(super.say())
    }
    
    //子類獨有方法
    subtract(){
     console.log(this.x-this.y)
    }
  }
  
  let son=new Son(5,3);
  son.subtract();
  son.sum();
tips: 繼承中的屬性或者方法查找原則:就近原則
  • 繼承中,若是實例化子類輸出一個方法,先看子類有沒有這個方法,若是有就先執行子類的
  • 繼承中,若是子類裏面沒有,就去查找父類有沒有這個方法,若是有,就執行父類的這個方法(就近原則)
  • 子類在構造函數中使用super,必須放到this前面(必須先調用父類的構造方法,再使用子類構造方法)
  • es6 中類沒有變量提高,必須先定義類,才能經過類實例化對象\
  • 類裏面的共有的屬性和方法必定要加this使用

2.this指向

  • constructor (構造函數)裏面的this 指向的是 建立的實例對象
  • 方法 誰調用了方法,那麼它的this就是指向它
var that //等於構造函數裏this 即ldh這個對象
  class Star{
    constructor(name,age){
        that=this
        this.name=name
        this.age=age
        this.btn=document.querySelector('button');
        this.btn.onclick=this.sing
    }
  }
  
  sing(){
    /* 這個sing方法裏的this,指向的是btn  這個按鈕,由於這個按鈕調用了這個函數 */
     console.log(this)
     console.log(this.name) //輸出undenfind
     console.log(that.name) //輸出ldh
   }
   
   dance(){ 
    /* 這個dance裏面的this 指向的是實例對象 ldh 由於是ldh調用了這個函數 */
    console.log(this)
   }
   
   let ldh=  new Star(ldh,18)
   ldh.dance()

3.構造方法和原型(模擬面向對象)

  • es5不使用prototype原型對象
function Star(name,age){
      this.name=name;
      this.age=age;
      this.sing=funtion(){
         console.log(我會唱歌) 
      }
   }
   var ldh=new Star('劉德華',18);
   var zxy=new Star('張學友',19);
   /* new多個,基本屬性不會,但sing方法會開闢多個不一樣的內存空間,存在內存浪費的現象 */。
  • es5使用構造函數prototype原型對象
function Star(name,age){
      this.name=name;
      this.age=age;
      Star.prototype.sing=funtion(){
         console.log(我會唱歌) 
      }
   }
   
   Star.prototype ={
    /*若是咱們修改了原來的原型對象,給原型對象賦值的是一個對象,則必須手動的利用constructor指回原來的構造函數*/ 
    constructor:Star
   }
   
   var ldh=new Star('劉德華',18);
   var zxy=new Star('張學友',19);
   ldh.sing()
   /* new多個,基本屬性不會,但sing方法會開闢多個不一樣的內存空間,存在內存浪費的現象 */。
  • 原型對象html

    • 原型是一個對象,咱們也稱爲prototype爲原型對象
    • 構造函數經過原型分配的函數是全部對象所共享的。
    • js規定, 每個構造函數都有一個prototype屬性,指向另外一個對象,注意這個prototype就是一個對象,這個對象的全部屬性方法,都會被構造函數所擁有。
    • 咱們能夠把這些不變的方法,直接定義在prototype對象上,這樣全部對象的實例就能夠共享這些方法
    • 通常狀況下,咱們的公共屬性定義的構造函數裏面,公共的方法咱們就放到原型對象上
    • 對象身上(ldh對象)系統本身添加一個__proto__指向咱們構造函數中的原型對象
    • ldh.__proto__和構造函數Star.prototype 是等價的
  • __proto__和 prototype 的區別ios

    • __proto__new出來的實例的的原型對象
    • prototype 是構造函數的原型對象git

      tips: es5的構造函數方法很好用,可是存在浪費內存的問題,能夠經過構造函數的原型對象來存放方法,使得方法在不一樣對象中共享,起到節約內存的做用。

4.原型鏈

  • 實例對象 proto (找不到的再向上找)-> 構造函數的原型對象 __proto__(找不到再向上找)->Object.prototype__proto__(找不到再向上找)-> null
  • js成員的查找機制es6

    • 當訪問一個對象的屬性(包括方法)時,首先查找這個對象自身有沒有該屬性 。
    • 若是沒有就查找它的原型(也就是__proto__指向的prototype原型對象)。
    • 若是尚未就查找原型對象的原型(object的原型對象)。
    • 依次類推一直找到Object爲止(null)。
function Star(name,age){
           this.name=name;
           this.age=age;
         }

        Star.prototype.sing=function(){
          console.log("我會唱歌");     
        }

        Star.prototype.sex='女' //構造函數原型成員 ,優先級中等
        Object.prototype.sex="男"//object對象的原型成員 ,優先級最低
        var ldh =new Star('劉德華',18)
        ldh.sex="男" //實例對象的原型成員 優先級最高
        console.log(ldh.sex)

        //打印這個實例向上找,能夠找到Object
tips: 每一個對象裏都有 __proto__這個屬性

5.利用原型對象,擴展內置對象方法

console.log(Array.prototype) 能夠打印js的一些關於數組的api

 //在Array對象上添加自定義方法
Array.prototype.sum=function(){
   var sum=0;
   for(var i=0;i<thsi.length;i++){
       sum+=this[i];
   }
   return sum;
 }
 
var arr=[1,2,3]; 
console.log(arr.sum())
var arr =new Array(11,22,33)
arr.sum();

//不可採用如下方法加入方法
 Array.prototype=
 {
  sum: function(){
       var sum=0;
       for(var i=0;i<thsi.length;i++){
       sum+=this[i];
    }
      return sum;
   }
 }
tips: 本身加的 原型方法會高亮,不可採用 對象的方式去添加原型方法,會覆蓋原先就存在的方法。

6.call 方法

  • call能夠調用函數。
  • 能夠改變這個函數的this指向。
  • 第一個參數是this的指向要被改變到這個參數的。
  • 第二個開始 就當作是普通函數的普通參數就能夠了,只是this指向改變了,但方法裏一些操做沒有改變
  • es5用call綁定this繼承了屬性
function fn(x,y){
     console.log('我想喝手磨咖啡');
     console.log(this);
     console.log(x,y);
   }
   
   var o={
      name:'andy'
   }
  
  fn.call() 
  
  /* 此時這個函數的this,就指向了o這個對象,指向哪一個對象根據第一個參數決定*/
  fn.call(o,1,2)  
  1. 父構造函數
  function Father(name,age){
    //this 指向父構造函數的對象實例
     this.name=name;
     this.age=age;
  }
  
  2. 子構造函數
  //這個score用的son本身的屬性
   function Son(name,age,score){
      //this 指向子構造函數的對象實例,
      //用call來調用Father這個構造函數,並把指向改爲子類的構造函數的this,就實現了繼承
      Father.call(this,name,age)
      this.score=score
    }
   var son=new Son('劉德華',18,200)
   console.log(son)

7. prototype 繼承方法

原型對象(prototype)繼承方法,經過原型鏈向上找規則,
Father實例(找不到向上找)->Father的原型對象的方法
就能夠繼承方法了,且子son方法定義本身的方法時不會影響到父github

//Father 是es5的構造函數
 son.prototype=new Father()
 son.prototype.constructor=son

8. 類的本質

類的本質其實仍是一個函數 咱們也能夠簡單的認爲類就是構造函數的另一種寫法面試

  • es5 經過構造函數+原型實現面向對象 編程有如下特色ajax

    • 構造函數有原型對象prototype
    • 構造函數原型對象prototype裏面有constructor指向構造函數自己
    • 構造函數能夠經過原型對象添加方法
    • 構造函數建立的實例對象有__proto__原型指向 構造的原型對象
  • es6正則表達式

    • class有原型對象prototype
    • class的prototype裏面有constructor指向構造函數自己
    • class能夠經過原型對象添加方法
    • class建立的實例對象有__proto__原型指向 構造的原型對象

9. 數組方法

  • forEach 迭代遍歷數組,break和retrun不會終止編程

    var arr= [1,2,3];
    arr.forEach((value,index,array)=>{
        console.log("每一個數組元素"+value)
        console.log("每一個數組元素的索引號"+index)
        console.log("數組自己"+array)
    })
    • filter 主要用於篩選數組json

      var
           arr=[12.66,4,88]
           var newArr=arr.filter((value,index,array)=>{
             return value>=2  //知足條件就把值放到新數組裏
           })
      tips:返回的是一個新數組,不會影響原來的數組
  • some

    主要用於檢測數組中的元素是否知足指定條件,通俗點查找數組中是否有知足條件的元素

var
   arr=[12.66,4,88]
   var flag=arr.some((value,index,array)=>{
     return value>=2  //知足條件就是true
   })
   
   arr=[12.66,4,88]
   var flag=arr.some((value,index,array)=>{
    if(value>30){
        return true  
    }
   })
tips:返回的是一個布爾值,若是查找到這個元素就返回true,再也不進行循環,效率更高。

10. 字符串方法

trim 去除左右兩邊的空格,但不會去除中間的空格

str.trim()

11. object.defineProperty()

定義對象中新屬性或修改原有的屬性

object.defineProperty(obj,prop,descriptor)

object.defineProperty的參數

參數 是否必需 類型 說明
obj true Object 目標對象
prop true String 需新定義或修改的屬性的名字
descriptor true Object 目標屬性所擁有的的特性
var obj={
     id:1,
     pname:"小米",
     price:1999
 }
 
 //對對象定義新屬性並賦值,之前的寫法
 obj.num=1000;
 obj.price=99;
 //如今的寫法
 
 Object.defineProperty(obj,'num',{      
 })

第三個參數descriptor的參數

參數 是否必需 類型 說明
value false mixed 設置屬性的值 默認undefined
writable false boolean 是否能夠重寫 默認false
ebumerable false boolean 目標是否能夠被枚舉(遍歷),默認false
configurable false boolean 目標屬性是否能夠被刪除或是否能夠再次修改特性true/false 默認爲false
tips: 注意新定義的descriptor 都是默認爲false 用obj={} 來定義的由於沒有定義是否能夠被XX操做因此都是true

12.函數

全部的函數都是Function的實例(對象),函數也是個對象,萬物皆對象

1、 函數的定義方式
1.自定義函數(命名函數)

function fn(){};

2.函數表達式(匿名函數)

var fun =function(){
    
}

3.利用new Function (不推薦,效率低)

new Function('參數1','參數2','函數體')
參數 是否必需 類型 說明
參數1 false String 第一個參數
參數2 false String 第二個參數
函數體 false String 第三個參數
tips:若是隻有一個參數那麼就是函數體

二 、 函數的調用方式
1.普通函數

this 指向window

function fn(){
   console.log('人生的巔峯') 
}

fn() (window.fn())
fn.call()

2.對象的方法

this指向o

var o ={
   sayHi:function(){
         console.log('人生的巔峯')  
   }  
 }
 
 o.sayHi();

3.構造函數

this 指向實例對象

function Star(){};

new Star();

4.綁定事件函數

this 指向是函數的調用者btn這個按鈕對象

//點擊了按鈕就能夠調用這個函數
btn.onclick=function(){};

5.定時器函數

this指向的是window

這個函數式定時器自動1秒鐘調用一次

setInterval(function(){     
},1000);

6.當即執行函數

this 指向window

(function(){
  console.log('人生的巔峯') 
})()
tips: 當即執行函數是自動調用
調用方式 this指向
普通函數調用 window
構造函數調用 實例對象,原型對象裏面的方法也指向實例對象
對象方法調用 該方法所屬對象
事件綁定方法 事件綁定對
定時器函數 window
當即執行函數 window

13.改變this指向

  • call

    1. 調用函數
    2. 能夠改變函數內部的this指向
var o={
        name:"1"
     }
     functon fn(a,b){
         console.log(a+b)
     } 
     fn.call(o,1,2)
tips: 後兩個參數是形參 用於參與fn的一些對象,主要用於在es5中實現繼承
  • apply

    1. 調用函數
    2. 能夠改變函數內部的this指向
    3. 主要應用 apply 藉助於數學內置對象求最大值和最小值。
var o={
        name:"1"
     }

     functon fn(a,b){
         console.log(a+b)
     }

    fn.apply(o,[1,2]) 
    var arr=[1,66,4]
    //若是不想改變this(指定對象)就寫個null,但不合適寫Math就好了
    Math.max.apply(Math,arr)
tips:參數必須是數組,但打印後倒是字符串或是數字(根據數組裏的數據類型,斷定)
  • bind

    1. 不會調用函數
    2. 能夠改變函數內部的this指向
    3. 返回的是原函數改變this以後產生的新函數(深拷貝)
var o={
       name:"1"
     }
     functon fn(a,b){
         console.log(a+b)
     }
     var f= fn.bind(o);
     f();
     //亦或者是
      functon fn(a,b){
         console.log(a+b)
      }.bind(this)

14. call、apply、bind總結

  • 相同點:均可以改變函數內部的this指向
  • 區別點:

    • call和apply會調用函數,而且改變函數內部this指向。
    • call和apply傳遞的參數不同,call傳遞參數aru1,aru2形式,apply必須數組形式[arg]
    • bind 不會調用函數,能夠改變函數內部的this指向
  • 主要應用場景:

    • call常常作繼承。
    • apply常常跟數組有關係,好比藉助於數學對象實現數組最大值和最小值
    • bind不調用函數,可是還想改變this指向,好比改變定時器內部的this指向,ajax的this指向

15. 嚴格模式

  • 做用:

    • 消除了js語法的一些不合理、不嚴謹、減小了一些怪異行爲。
    • 消除代碼運行的一些不安全之處,保證代碼運行的安全。
    • 提交編譯器效率,增長運行速度。
    • 禁用了es的將來版本中可能會定義的一些語法,爲將來新版本的js作好鋪墊。好比一些保留字如:class,enum,export,extends,import,super不能作變量名
  • 變化

    • 咱們的變量必須先聲明再使用
    • 咱們不能隨意刪除已經聲明好的變量
    • 在嚴格模式中全局做用域中函數中的thisundefined而不是window
    • 之前構造函數不加new也能夠調用,當前普通函數,this指向全局,在嚴格模式下不能使用了,this指向undefined
    • new 實例化的構造函數指向建立的對象實例
    • 定時器的this 仍是指向window
    • 函數不能有重名的參數
    • 函數必須聲明在頂層,不容許在非函數的代碼塊內聲明函數。好比if和for的花括號裏定義函數,但函數嵌套函數是能夠的。
//爲整個腳本開啓嚴格模式

         <script>
         'use strict';
          </script>

          <script> 
          (function()){
            'use strict';
          }() 
          </script> 

          //爲某個函數開啓嚴格模式

          <script> 
             function fn(){
                'use strict';
                 /*裏面的代碼按照嚴格模式執行*/
              }

              function fun(){
                 /*裏面的仍是按照普通模式執行*/
               }

          </script>
tips:兼容ie10以上,ie10如下會忽略這個模式

16. 高階函數

高階函數- 函數能夠做爲參數傳遞,參數的接收方就是高階函數,即 fn

function fn (a,b,callback){
     console.log(a+b);
     callback && callback()
  }

 fn(1,2,function(){
    console.log(我是最後調用的);
 })

17. 閉包

  • 閉包指有權訪問另外一個函數做用域中變量的函數,簡單理解就是,一個做用域能夠訪問另一個函數內部的局部變量,(closure 是閉包)此時就有閉包的產生,閉包也是高階函數
  • 這裏fn是閉包,fun調用了fn的變量,也就是被調用變量所在的函數,就是閉包函數
function fn (){
     var num=10;
     function fun(){
      console.log(num)
     }
     fun ()
 }

fn
  • 咱們fn外面的做用域能夠訪問fn 內部的局部函數
function fn(){
    var num=10;
    return function(){
     console.log(num)   
    }
}

//這裏f保存的是個函數
var f=fn()
//這裏輸出的是num
f()
for (var i=0;i<lis.length;i++){
/*利用for循環建立了4個當即函數*/
/*當即執行函數也成爲小閉包由於當即執行函數裏面的任何一個函數,均可以使用它的i這個變量*/


/*這裏的i是從底下的那個i傳進來的*/
(function(i){

lis[i].onclick=function()  {
    console.log(i)
 }
})(i)
tips:閉包的主要做用:延伸變量的做用範圍。但閉包容易照成內存泄漏,它一直不釋放資源,閉包總結:閉包是一個函數,閉包延伸了做用域範圍

18. 遞歸

  • 函數內部本身調用本身,這個函數就是遞歸函數,遞歸函數必須加退出條件,利用遞歸函數求1-n的階乘。
function fn(n){
      if(n==1) return 1;
       return n*fn(n-1);
    }

    console.log(fn(3))
    執行過程

    return 3*fn(2)
    return 3*(2*fn(1))
    return 3*(2*1)
    return 6
  • 用遞歸求斐波那契數列(兔子序列)
function fb(n){
      if(n===1 || n===2){
          return 1
      }
      return fn(n-1)+fb(n+2);
    }

    console.log(fb(3))
    console.log(fb(3))
  • 用遞歸來遍歷數據
var data=[
     {
       id :1,
       name:'家電'
       goods':[
        {
           id :11,
           name:'家電11'
        },
         {
           id :12,
           name:'家電12'
        }
       ]
     }
      {
       id :2,
       name:'家電2'
       goods':[
        {
           id :13,
           name:'家電13'
        }
       ]
     }
    ]

    function getID(json,id){
     var o ={};
     json.forEach(function(item)) {
      if(item.id==id){
         console.log(item);
         o=item;    
      }else if(item.goods&&item.goods.learth>0){
         o= getID(item.goods,id)
       }
      }
     } 
     console.log(getID(data,1))

tips: 開闢內存空間,容易照成死遞歸,出現棧溢出。在forEach裏面執行遞歸,不加退出條件,循環已經幫你加了。

19. 淺拷貝和深拷貝

  • 淺拷貝只是拷貝一層,更深層次對象(對象或數據等複雜數據類型)級別的只拷貝引用。
    1.for 循環實現淺拷貝
var obj={
     id:1,
     name:"andy", 
     msg:{  //這個對象是深層次對象會被淺拷貝,會被拷貝地址,修改o同時會修改obj,這個就是淺拷貝
         age:18
     }
    }
    
     var o={}
     for(var k in obj){
      //k 是屬性名
      // obj[k] 屬性名
       o[k]=obj[k];
     }
     console.log(o);
     o.msg.age=20;
     console.log(obj)

2.es6的語法糖實現淺拷貝

Object.assign(o)
  /*主要用來對,對象賦值, key值相同的會覆蓋
  其餘沒進行賦值的不會處理,由於是淺拷貝因此會影響原數組
  */
  • 深拷貝拷貝多層,每一級別的數據都會拷貝
    1.用遞歸的方式來實現深拷貝
function deepCopy(newobj,oldobj){
     for(var k in oldobj){
      var item=oldobj[k];
      if(item instanceof Array){
        newobj[k]=[];
       //判斷是不是數組
        deepCopy(newobj[k],item)
      }else if(item instanceof Object){
        //判斷是不是對象
         newobj[k]={};
         deepCopy(newobj[k],item)
      }else{
       // 簡單數據類型
        newobj[k]=item;
       }
      }
    }
2.用JSON.stringify()和 jSON.parse() 來實現 深拷貝
tips: 數組也屬於Object 因此要把Array判斷寫在object的前面。

總結:淺拷貝,深層次的數據如數組和對象只會拷貝引用,修改拷貝後的數據會同時修改原來的被拷貝的的數據,深拷貝,是對數組和對象開闢不一樣的空間,被拷貝的的數據。

20. 正則表達式

   靈活性、邏輯性和功能性很是的強,
能夠迅速地用極簡單的方式達到字符串的複雜控制

  • 建立正則表達式
    1.利用RegExp 對象來建立 正則表達式
var regexp=new RegExp(/123/)
    console.log(regexp)

2.利用字面量,建立正則表達式,即用//即註釋的中間寫上規則匹配就是正則表達式了

var rg=/123/;
     /*
      可用test 方法來檢測是否符合正則表 返回true或false
     */
     var rg=/123/;
     console.log(rg.test(123));
  • 邊界符 ^ $
var rg=/^abc/ ^匹配的是開頭,這裏的是abc
    var rg=/^abc$/ 精確匹配 只有輸入abc 纔會匹配
  • 字符類 []
    表示有一系列字符可供選擇,只要匹配其中一個就能夠了。這個只能多選一要和量詞符,匹配使用。量詞是設定某個模式出現的次數。
/* 只要包含a,或者b,或c,其中一個就能夠了 */
     var rg=/[abc]/

    /* 只能選擇一個a或者b或者c其中的一個 三選一 */
       var rg=/^[abc]$/

    /* 只能選擇一個a-z,26字符中其中的一個字符,26選一
    表示到a到z的範圍 能夠在[]中添加各類字符組合
    */  
      var rg=/^[a-zA-z]$/

    /* 若是中括號裏 ^ 表示取反的意思 不要和邊界符 ^ 混淆 取反即      如下就不能是 a-z和A-z 
    */ 
      var rg=/^[^a-zA-z]$/
  • 量詞符
      若是前面的那個沒有加上中括號,那麼就做用於量詞符前面那個的字符。有中括號就按照中規則裏匹配的規則去實現。
//* 至關於>=0 能夠出現0次或者不少次

    var rg=/^a*$/;
    console.log(rg.test('')) 
    console.log(rg.test('aaa'))

    //+ 至關於>=1 能夠出現1次或者不少次,不能不出現,即0次
      var rg=/^a+$/;
     console.log(rg.test('')) 
    console.log(rg.test('aaa'))

    //? 至關於 1 || 0  能夠出現1次或者0次 
     var rg=/^a?$/;
     console.log(rg.test('')) 
     console.log(rg.test('a')) 
     console.log(rg.test('aaa')) 

    //{3}就是重複出現3次

    var rg=/^a{3}$/;
    console.log(rg.test('')) 
    console.log(rg.test('aa')) 

    console.log(rg.test('aaa')) 

    //{3,}出現大於等於3

    console.log(rg.test('')) 

    console.log(rg.test('aaa'))

    //{3,16}出現大於等於3而且小於等於16

    var rg=/^a{3,16}$/;

    console.log(rg.test(''))

    console.log(rg.test('a'))
  • 量詞符和模式匹配
模式是 :[a-zA-z] 某個規則
    量詞符:{6,16} 這個規則的裏字符可出現的次數 即只能出現6-16個a-zA-z 裏的字符 且所有合起來只能有6-16個。
    var rg=/^[a-zA-z]{6,16}$/
  • 優先級 用小括號來表示優先級
//這裏有小括號因此表示 abc 重複3次
    var rg=/^(abc){3}/
    //這裏沒有小括號 c 重複3次
    var rg=/^abc{3}/
  • 能夠用菜鳥正則表達式的測試工具 菜鳥工具

      菜鳥工具

  • 預約義類 簡寫正則
預約類 說明
d 匹配0-9之間的任一數字,至關於[0-9]
D 匹配0-9之外的字符,至關於1
w 匹配任意的字母、數字、和下劃線,至關於[A-Za-z0-9_]
W 匹配任意的字母、數字和下劃線之外的字符,至關於2
s 匹配空格(包括換行符、製表符、空格符等),至關於[trnvf]
S 匹配非空格(至關於3
  • 正則裏還能夠用 | 表示或者的意思
//座機號碼驗證 010-12345678 0591-1234567

 //第一種
 var reg=/^\d{3}-\d{8}|\d{4}-\d{7}$/
 //第二種
 var reg=/^\d{3,4}-\d{7,8}$/
//手機號碼的正則表達式
 var rg=/^1[3|4|5|7|8]\d{9}$/;
//qq號的正則 10000開始
var rg=/^[1-9]\d{4,}$/
  • replace 替換
var str=str.replace(/andy/,bady)
參數 說明
第一個參數 被替換的字符串或者正則表達式
第二個參數 替換爲的字符串

返回值 是一個替換完畢的新字符串

tips: 正則表達式裏面不須要加引號, 無論是數字型仍是字符串型,正則表達式的中間不要有空格即//裏添加的內容不要用空格來間隔

如下都是es六、es7的知識點

1.let關鍵字

  • let關鍵字聲明的變量具備塊級做用域,用來替代var ,主要用來防止內層變量覆蓋外層變量,防止循環變量變成全局變量。
if(true){
         let a=1;
         var b=3
     }

     console.log(a) //訪問不到 undefined
     console.log(b) //訪問的到,輸出3
  • let關鍵字聲明變量,沒有變量提高未定義不能訪問
  • 具備暫時性死區特性
var num =10
      if(true){
        console.log(num)  undefined
        let num=1
      }

     /* num輸出在塊級做用域裏,使用的是塊級的做用域定義的變量,並且是在未定義前輸出因此是undefined */
  • let 解決循環的變量問題
for (var i=0;i<10;i++){
           console.log(i)
           setTimeOut(function(){
              console.log(`i:${i}`)
        })
      }
      在var定義的變量下,定時器裏輸出的都是10 
      由於此時循環已經結束了,i是最後的一個值。

      用let 能夠正常循環輸出

2.const關鍵字

  • 聲明的常量具備塊級做用域
  • 必需要賦初始值
  • 常量賦值後,內存地址(值)不能修改,分兩種狀況

    • 對於複雜數據類型,裏面的值能夠更改,但數據值自己不能更改
    • 對於普通數據類型,值就是不能更改
const a =1
       a=3 //報錯,值不能更改
      const arr=[1,2]
      arr[0]=3  //可更改,只是更改結構內部的值   arr=[3,2]
      arr=[34,44] //不可更改總體都更改,是地址的更改,不容許
  • 不存在變量提高 (先聲明再使用)
tips: 若是讓對象裏的屬性不可進行修改可使用es5的方法 Object.freeze(arr) 此時 arr內部的屬性也不能更改

3.解構賦值

  • 數組解構容許咱們按照一一對應關係從數組中提取值,而後將值賦值給變量
let [a,b,c]=[1,2,3] || [];
    console.log(a,b,c,d,e)
    a 、b、c 輸出 1,2,3 d,e是undefined
  • 對象解構賦值
let person ={name:'zhangsan',age:20}
    let {name,age}=person || {}
    console.log(name) //zhangsan
    console.log(age) // 20
    let {name:myName,ages:myAge}=person
    console.log(myName,myAge) //也能夠輸出
  • 解構和擴展運算符一塊兒的使用
//第一種狀況,把整個的對象賦值給另外一個讀寫
    let user = { a: 1,b: 2,c: 3,d: 4,e: 5}
    let 
    {
      aa = { a: user.a, b: user.b }, 
      bb = { ...user } 
    } = {}

    /*
    第二種狀況,能夠把對象的值分配到不一樣的對象
    */
    let users = {}, userDetails = {};
    ({ a: users.a, b: users.b, ...userDetails } = user);
    console.log(users, userDetails)

    //users {a:1,b:2}  userDetails {c:3,d:4,e:5}
  • 對象解構能夠嵌套獲取值
const Tom={

         name: 'Tom jones',
         age:25,
         family:{
             mother: 'Norah Jones',
             father: 'Richard Jones',
             brother: 'Howard Jones'
         }
     }

     //只有在變量是underfine時,才能使用默認值 null false 0 都是有值的
     const { father:f,mother:m,brother='sss' } = Tom.family || {} ;

    //以上的f、m 是別名 輸出用別名
  • 用數組解構來交換值
let a=10
  let b=20
  [a,b]=[b,a]

  console.log(a,b) //a輸出 20 b輸出10
tips: 第二種狀況,必定要加上括號。

4.箭頭函數

  • 箭頭函數是用來簡化函數定義語法的
function sum(num1,num2){
        return num1+num2
    }

    const sum=(n1,n2)=>{
      return n1+n2    
    }

    //以上代碼只有一行,且return這行代碼就能夠簡寫爲
    const sum=(n1,n2) => n1+n2
  • 箭頭函數的形參個數 只有一個時也能夠省略個數
  • 箭頭函數不綁定this,箭頭函數沒有本身的this關鍵字,若是在箭頭函數中使用this,this關鍵字將指向箭頭函數定義位置中的this
  • 經典面試題
var num=10
      let obj={
          num:1
          say:(){
              console.log(this.num)
          }
      }
     obj.say() //這裏輸出的是10
  • 具名的的箭頭函數
const gg=()=>{
        console.log(1)
     }
  • 順口溜 刪掉function關鍵字,加上一個胖箭頭,沒有參數加括號,一個參數可選擇(加不加括號),多個參數逗號分隔(要加括號的)
  • 箭頭函數不執行this 綁定
  • 不適用箭頭函數的狀況

    • 構造函數
    • 爲原型添加方法的時候
    • 各類綁定事件
    • 在函數中使用arguments對象的時候
1.做爲構造函數,一個方法須要綁定到對象 
       const Person=function(name,points){
           this.name=name
           this.points=points;
       }
       const jelly=new Person('jelly',5);

      2.原型添加方法
       Person.prototype.updatePoints=function(){
           this.points++
           console.log(this.points)
       }

      3.事件
       const  button=document.querySelector('.zoom');
       button.addEventListener('click',function(){

       })

      4.須要使用arguments

      const sum =function(arguments){
        /*arguments不是個真正的數組 須要用Array.from 轉換 或用擴展運算符[...arguments]來轉換*/   
       return Array.from(arguments).reduce((prevSum,value)=>pervSum+value,0 )

       }
tips: 對象是不產生做用域,指向的s是全局window,因此箭頭函數的this,指向的是window,因此這裏輸出的是10

5.剩餘參數

  • 剩餘參數語法容許咱們將一個不定數量的參數表示爲一個數組
//定義個方法
    const sum =(...args)=>{
         let total=0;
         args.forEach(item=>{
            total+=itme 
         })
         return total
    }
    sum(10,20) //args裏保存着10和20
    sum(10,20,30)//args裏保存10,20,30
  • ...args,參數是一個數組的組合
  • 剩餘參數和數據解構結合
let ary1=['張三','李四','王五']
    let [s1,...s2]=ary1
    s1 //存着張三
    s2 //接收剩餘參數成爲個新數組,存着李四和王五

6.擴展運算符

  • 擴展運算符能夠將數組或者對象轉爲用逗號分隔的參數序列
let ary=[1,2,3];
    ...ary //1,2,3 轉爲去掉括號的用逗號分隔的參數序列
    console.log(...ary) 1 2 3
  • 擴展運算符可用於合併數組,生成的是新數組
let ary1=[1,2,3]
    let ary2=[4,5,6]
    ...ary1  //1,2,4 
    ...ary2  //4,5,6
    //第一種
    let ary3=[...ary1,...ary2]
    //第二種  -- push方法能夠有多個參數
    ary3=ary1.push(...ary2)
  • 擴展運算符可將僞數組轉爲真正的數組,就可使用數組的一些方法
var Odivs=document.getElementsByTagName('div')
    console.log(Odivs) //僞數組 可迭代遍歷但沒有數組方法
    var ary=[...Odivs]
    ary.push('a')
    console.log(ary);
  • 擴展運算符是深拷貝,修改使用新生成的數組,不影響原來數組的值
  • 擴展運算符的應用實踐
1. //把二維數組擴展成對象數組
     [...array[1],...Array[1]] 
     輸出
     [object,object]

    2. //可用來代替apply方法
     const fruit=['apple','bananas','pear'] 
     const newFruit=['orange','mongo']

     //用apply合併數組,apply後面跟着的參數是數組
     fruit.push.apply(fruit,newFruit) 
     //用擴展運算符來合併
     fruit.push(...newFruit)
  • 擴展運算符適用於函數的傳參

7 array.from() --數組的擴展方法

  • 能夠把僞數組轉爲真正的數組
  • 方法還能夠接收第二個參數,做用相似於數組的map方法,用來對每一個元素進行處理,將處理的後的值放入返回的組數
例子1
var arrayLike={
    "0":"1",
    "1":"2",
    "length":2 
}
Array.from(arrayLike,item=>item*2)

例子2 
const todos=document.querySelectorAll('li');
const names=Array.from(todos,todo=>todo.textContent);
console.log(names)
  • 能把字符串也轉換成數組
const str='abc'
 console.log(Array.from(str))  [a,b,c]

8 array.find() --數組的擴展方法

  • 用於找出第一個符合條件的數組成員,若是沒有找到返回undefined
let ary=[{
    id:1,
    name:'張三'
 },{
    id:2,
    name:'李四'
 }
]

let target= ary.find(item=> item.id==2 )

9 array.findIndex() --數組的擴展方法

  • 用於找出第一個符合條件的數組成員的位置,若是沒有返回-1
let ary=[10,20,50]
const index= ary.findIndex((item,index)=>itme>15)
console.log(index)

10 array.includes() --數組的擴展方法

  • 表示某個數組是否包含某個元素
  • 字符串也可以使用,可傳入第二個參數表示第幾個開始
let ary=["a","b",c]
 ary.includes("a")

11 array.of() --數組的擴展方法

當前方法能夠彌補 new Array 構造方法返回結果不一致問題。

/*當參數只有一位的時候,返回的是長度爲1的數組 [undefined*1],而不是[1] 只有當參數是多個的狀況下才會返回正確的數據*/
new Array(1)
array.of(1)  輸出的是[1]

12 array.every() --數組的擴展方法

當遍歷時遇到false時,就不執行了,返回false

13 模板字符串 --String的擴展方法

  • 做用就是字符串能夠解析變量,用於字符串拼接 使用反引號
let name=`帳上`
let sayHello =`hello${name}`
  • 模板字符串中能夠換行,寫的比較美觀
let result={
    name:"Zhangsan",
    age:20
}

let html=`
 <div>
   <span>${result.name}</span>
    <span>${result.age}</span>
</div>
`
  • 模板字符串中能夠調用函數、表達式等
const fn=(){
    return '我是fn函數'
  }
  
 let html=`我是模板字符${fn()}`
 
  const template=`
  <div class="greet">
    <p> Hello </p>
  </div>
  `.trim()
  
  //模板字符串自己就是字符串,因此可使用字符串方法
  • 模板字符串的實戰應用
function renderTodos(todos){
      return (
        `<ul>
            ${todos.map(todo=>`
              <li>
                 ${todo.name} ${todo.completed?'√':'X'}
              </li>`).join('')}
       </ul> `
      )
   }

 //map 返回的是數組 循環渲染有,因此用join 去除
  • 模板字符串的高級運用
const user='Mary';
const topic='learn to use markdown'
//模板字符串加方法
function highLight(strings,...values){
 //strings 輸出的是:has commented on your topic
 //values 輸出的是:user和topic
}
const sentence= hightlight `${user} has commented on your topic ${topic} `
  • 使用 DOMPurify.sanitize 來防止xss攻擊,要引入 dompurify的purify.js

14 startsWith()、endsWith()

--String的擴展方法

  • startsWith():表示參數字符串是否在原字符串的頭部,返回布爾值
  • endsWith():表示參數字符串是否在原字符串的尾部,返回布爾值
  • 大小寫敏感的
  • 可傳遞第二個參數, 從第幾個參數開始
let str='hello world';
str.startsWith('Hello') //true
str.endsWith('!') 、//true

//可傳遞第二個參數, 從第幾個參數開始  
str.startsWith('Hello',6)

15.repeat --String的擴展方法

  • repeat方法表示將原字符串重複n次,返回一個新字符串
  • 能夠應用於讓字符串對齊
'x'.repeat(3) // "xxx"
'hello'.repeat(2) //hellohello
const id  ='510300198007300366x'
 const fan ='I love Laravist.'
 function padder(string,length=25){
    return `${'',repeat(Math.max(length-string.length,0))}${string}`
 }

 console.log(padder(id))
 console.log(padder(fan))

16. for or循環遍歷

支持數組、字符串等 但目前版本不支取對象的循環

Array.protype.frist=function() {
    return this[0]
}
const fruits=['Apple','Bannana','Orange','Mango'];
fruits.describe='My favorite fruits';

for(let index in fruits ){
   console.log(fruits[index] ) 會輸出多餘的值 
 }

for(let index of  fruits ){
   console.log(index ) 只輸出數組內的值 能夠 break
 }

//迭代器
for(let [index,fruit] of fruits.entries() ){
   console.log(index,fruit ) 只輸出數組內的值 能夠 break
 }

17.set 數據結構

  • es6 提供了新的數據結構Set。它相似於數組,可是成員的值都是惟一的,沒有重複的值。
const s=new Set()
s.size //看s的長度
  • es6 能夠進行數組去重
const s3=new Set(["a","b","b"])
//用擴展運算符,變成用逗號分隔的
const arr=[...s3]
  • set 內置方法

    • add(value):添加某個值,返回Set結構自己
    • delete(value):刪除某個值 返回一個布爾值,表示刪除是否成功
    • has(value): 返回一個布爾值,表示該值是否爲Set的成員
    • clear(value):清除全部成員,沒有返回值
tips: set的方法可使用鏈式調用
  • set 遍歷
const s5=new Set(['a','b','c'])
 s5.forEach(value=>{
     console.log(value)
 })

18. 遞歸

//接口返回數據結構--是個數組

0: {menu_id: 92, menu_name: "微信公衆號", menu_fid: 0, menu_val: "92_wechat_publicnumber"}
1: {menu_id: 1, menu_name: "學校管理", menu_fid: 0, menu_val: "1_school"}
2: {menu_id: 2, menu_name: "教師管理", menu_fid: 0, menu_val: "2_psychologist"}
3: {menu_id: 3, menu_name: "學生管理", menu_fid: 0, menu_val: "3_counseling"}
4: {menu_id: 4, menu_name: "量表中心", menu_fid: 0, menu_val: "4_scale"}
5: {menu_id: 5, menu_name: "心理諮詢", menu_fid: 0, menu_val: "5_advisory"}
6: {menu_id: 6, menu_name: "異常反饋", menu_fid: 0, menu_val: "6_abnormal"}
7: {menu_id: 7, menu_name: "活動管理", menu_fid: 0, menu_val: "7_activity"}
8: {menu_id: 8, menu_name: "在線求助", menu_fid: 0, menu_val: "8_help"}
9: {menu_id: 9, menu_name: "心理課堂", menu_fid: 0, menu_val: "9_classroom"}
10: {menu_id: 10, menu_name: "心理實驗", menu_fid: 0, menu_val: "10_experiment"}
11: {menu_id: 11, menu_name: "訂單管理", menu_fid: 0, menu_val: "11_order"}
12: {menu_id: 12, menu_name: "數據分析", menu_fid: 0, menu_val: "12_data"}
13: {menu_id: 14, menu_name: "學校列表", menu_fid: 1, menu_val: "14_school_list"}
14: {menu_id: 15, menu_name: "學校資訊", menu_fid: 1, menu_val: "15_information_list"}
15: {menu_id: 17, menu_name: "學校橫幅", menu_fid: 1, menu_val: "17_schoolad_list"}
16: {menu_id: 18, menu_name: "老師列表", menu_fid: 2, menu_val: "18_psychologist_list"}
17: {menu_id: 19, menu_name: "老師導入", menu_fid: 2, menu_val: "19_teacher_import"}
18: {menu_id: 20, menu_name: "發送信息", menu_fid: 2, menu_val: "20_edit_notice"}
19: {menu_id: 21, menu_name: "學生列表", menu_fid: 3, menu_val: "21_counseling_list"}
20: {menu_id: 22, menu_name: "學生導入", menu_fid: 3, menu_val: "22_counseling_import"}
21: {menu_id: 23, menu_name: "發送信息", menu_fid: 3, menu_val: "23_edit_cou_notice"}
22: {menu_id: 24, menu_name: "用戶統計", menu_fid: 3, menu_val: "24_user_count"}
23: {menu_id: 25, menu_name: "綜合檔案", menu_fid: 3, menu_val: "25_comprehensive_file"}
24: {menu_id: 26, menu_name: "量表分類", menu_fid: 4, menu_val: "26_scale_shape"}
25: {menu_id: 28, menu_name: "量表權限", menu_fid: 4, menu_val: "28_scale_rights"}
26: {menu_id: 29, menu_name: "測評查詢", menu_fid: 4, menu_val: "29_assess_search"}


//根據fid生成帶孩子的二級樹形結構--只有二級就簡單點

getJsonTree (data, fId) {
      let itemArr = [];
      data.forEach(item => {
        const { menu_id = 0, menu_fid = 0, menu_name = '', menu_val = '' } = item || {}
        if (menu_fid === fId) {
          let newNode = {
            id: menu_id,
            label: menu_name,
            value: menu_val,
            checkAll: false,
            checkedOptions: [],
            options: this.getJsonTree(data, menu_id) //第一個是0寫死的id找不到父親的,找到的都是當父親的,第二個就是把本身的id當作是fid 去找它的孩子
          };
          itemArr.push(newNode);
        }
      })
      return itemArr;
    },

// 孩子的數組,特殊狀況就用這個來代替 this.getJsonTree函數 (只限於二級)

    getChild (data, fId) {
      let itemArr = [];
      data.forEach(item => {
        const { menu_id = 0, menu_fid = 0, menu_name = '', menu_val = '' } = item || {}
        if (menu_fid === fId) {
          let newNode = {
            label: menu_name,
            value: menu_val,
          };
          itemArr.push(newNode);
        }
      })
      return itemArr;
    },

19. 對象字變量的擴展

es6 對象 變的更增強大

const name='Lara'
 const age=2

 const keys=['name','age']
 const values=['lara',2]
 
 const laravist={
  [keys.shift()]:values.shift(),
  [keys.shift()]:values.shift(),
  [keys.shift()]:values.shift(),
 }

20. promise

  • 解決回調地獄
const p=new Promise(reslove,reject)=>{
   setTimeout()=>{
     reject(Error('Error'))  
   }  
 })

 p.then(data=>{console.log(data)})
  .catch(err=>{console.log(err)})
tips: 在reject中使用Error返回錯誤信息時,使瀏覽器正肯定位到是reject那行發出的錯誤信息,而不是catch那行。
  • Promise all 同時調用多個promise
const userPromise=new Promise((resolove,reject)=>{
  setTimeout(()=>{
      reslove(['mojom','vanpe'])
  },2000)    
})

const moviePromise=new Promise(()=>{
  setTimeout(()=>{
      reslove({name:"摔跤",rat:9.2})
  },500) 
})


 Promise.
  all([userPromise,moviePromise])
 .then(responses=>{
   console.log(responses)
 })
 .catch(responses=>{
  console.log(responses)
 })
tips: Promise all 當以上全部 promise都正確執行時,才返回正確的,不然會被 catch捕獲。
  • Promise race 同時調用多個promise

當第一個調用的promise 正確執行時就在then中返回結果,否則就在catch中返回

21. Symbol

  • Symbol是js的第七種數據類型, 其餘6種:Undefined、Null、Boolean、Number和String,複雜的數據類型Object
  • 主要用來標識惟一key,因爲當前屬性不能用普通的方法進行遍歷,因此能夠當私有屬性,對於key值會重複的場景就可使用Symbol來對其惟一標識
const peter=Symbol('peter');
 const student=Symbol('student');
 //如下nina兩個key值重複,因此用Symbol來標識
 const classRoom={
   [Symbol('lily')]:{grade:60,gender:'female'},
   [Symbol('nina')]:{grade:60,gender:'female'},
   [Symbol('nina')]:{grade:60,gender:'female'},
 }
 
//for 循環不能遍歷
 for(let key of classRoom){
     console.log(key) //輸出[]
 }

//另類遍歷的方法
 const syms=Object.getOwnPropertySymbols(classRoom).map(sym>classRoom[sym])
 console.log(syms)

tips:classRoom[sym] 不能改爲 classRoom.sym 這裏會執行 classRoom['sym']但classRoom數據裏並無sym這個屬性名

22. eslint 代碼規範

  • eslint 會找當前目錄的.eslintrc.js文件,若是找不到就往上級找
  • 全局使用某個對象 好比 Vue 可使用,可不對eslint的規則進行配置
/* globals Vue */
 
 .eslintrc.js 文件中
  globals: {
    Yx: true
  }
  • 禁用某條規則
/* eslint-disable no-new */
  • 開啓某條規則
/* eslint-enable no-new */
  • eslint 可使用外部的插件
{
     "plugins":["markdown"]
 }

23 Reflect.ownKeys()

靜態方法 Reflect.ownKeys() 返回一個由目標對象自身的屬性鍵組成的數組。

const object1 = {
  property1: 42,
  property2: 13
};

var array1 = [];
console.log(Reflect.ownKeys(object1));
// expected output: Array ["property1", "property2"]

console.log(Reflect.ownKeys(array1));
// expected output: Array ["length"]

24. parseInt

轉化爲整形

//可使用+也可隱士轉化爲數字
 +'243'

25. class

  • 方法名能夠經過計算屬性命名並可進行調用
  • 不能進行變量提示,必須先聲明再引用
let methodName = 'info'
  class User {
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    
    [methodName](){
         console.log(1)
      }
  }
  • 繼承
class student extends User {
    constructor(name,age){
        super(name);   
      /*super的做用及原理
       做用 :繼承父類,等同於User.call(this,name)調用基類的構造函數
       原理:  student.prototype=new User()
       類的原型被改變了,可是類的原型的構造函數的也改變了,要指定構造函數爲student
        student.prototype.constructor =student
      */
       this.age=age;
    }
  }
  • 擴展內置對象

爲Array 添加本身的方法

class Movie extends Array {
  constructor(name,...items){
     super(...item)
     this.name=name
    }
    
   add(movie){
   //
    this.push(movie)
  }    
}

const movies=new Movie('favorite movies',
{name:'rr1',score:8.7},
{name:'rr2',score:99.7},
{name:'rr3',score:91.7}
)

movies.add() //添加內容

26. Iterator

遍歷器(迭代器)

const colors=[1,2,3]
const iterator= colors[Symbol.iterator]()
iterator.next()

/*輸出*/
Object{value:1,done:false }
iterator.next()

/*輸出*/
Object{value:2,done:false }
iterator.next()

/*輸出*/
Object{value:3,done:false }
iterator.next()

/*輸出*/
Object{value:undefined,done:true}
tips:
當done爲true時遍歷就結束了,輸出一個方法時有包含Iterator,就是遍歷器了,好比數組的 keys,entries,
values
  • 遍歷器內部原理
//實現一個Array.values
Array.prototype.values=function(){
 let i = 0;
 let items = this;
 return{
  //返回一個函數,造成閉包,能夠進行累加
  next(){
    const done =i > = items.length;
    const value = done?undefined:items[i++]
    return{
        value,
        done
     }   
   }   
  }
}

for of 的運行機制

for(const itme of color){}
//of調用,colors[Symbol.iterator]() 這個屬性。 並把裏面的value值賦值給color

27. generator (可不學,直接看async、await)

  • generator是生成器,能夠開始、暫停 ,最終生成的是個遍歷器(迭代器);
function* listColors(){
   let i=0;
    yield i; //返回
   i++;
    yield i;
   i++;
    yield i;
 }

//生成了遍歷器
const colors=listColors();

colors.next()
/*輸出*/
Object{value:0,done:false}

colors.next()
/*輸出*/
Object{value:1,done:false}

colors.next()
/*輸出*/
Object{value:2,done:false}

colors.next()
/*輸出*/
Object{value:undefined,done:true}

const colors=[1,2,3]
function* loop(repos){
 console.log(colors)
 for(const repo of repos){
    yield repo
 }
}
const repoGen=loop(repos)
  • 在項目中的實際應用(異步轉同步)
//進行ajax方法
 function ajax(url){
   axios.get(url).then( res => 
   執行成功後再執行下一步
   userGen.next(res.data)
  )     
}
//生成器 
function* steps(){
  const users = yield ajax('https://api.github.com/users');
  const firstUser = yield ajax(`https://api.github.com/users/${users[0].login}`)
  const followers = yield ajax(firstUser.followers_url);
}
const userGen =steps()
userGen.next()

28.proxy

  • 添加、重寫 對象上的默認方法,格式化默認值。
const person = {name:'laravist',age:2000};
 const personHandle={
   //獲取值
   get(target,key){
     //target:原目標; key:鍵值
     //把屬性值都轉換成大寫
      return target[key].toUpperCase(); 
    }
   //設置值
   set(target,key,value){
     //去掉空格
     if(typeof value==='string'){
       target[key]=value.trim()
     }
    }
 }
 const personProxy = new Proxy(person,personHandle)
 personProxy.name=' codecasts '
 console.log(personProxy.name)
 // 輸出:CODECASTS  --去去掉空格並轉換成大寫
  • 實際應用
// 安全挾持
const safeHandler = {
  set(target,key,value){
      //找相相似的鍵
      const likekey = Object.keys(target).find(k=>k.toLowerCase()===key.toLowerCase());
      //若是找到就不讓其賦值
      if(!(key in target) && likekey ){
        throw new Error(` Oops! looks like we already have a property ${key} but with the case of ${likeKey}`)    
       }
   }  
}

const safetyProxy=new Proxy({id:2}, safeHandler); 
safetyProxy.ID=5  /*會報錯,賦值已經被挾持了只要和id這個鍵值相相似的 好比 Id ID iD 都不讓賦值*/

29.set

  • 惟一的數組
  • 不能經過索引值來獲取值
// 定義一個set
 const colors=new Set()
 colors.add(4)//添加元素
 colors.delete(4)//刪除
 colors.has(4)//檢驗是否存在

 /*能夠用正常的數組循環方式進行循環*/
 for(let color of colors ){
   console.log(color)
 }
 
 colors.forEach(item=>{
     console.log(item)
 })
  • 可經過擴展運算符轉換成數組
const colorsSet=new Set([1,2,3,4,4,4,4])
 const colorsArr=[...colorsSet]
 // 或者能夠經過array.from() 來進行轉換

30.WeakSet

  • 保存值的類型只能是對象
  • 沒有set同樣的clear方法,有自動清理功能、防止內存泄漏
  • 不能對他進行遍歷
const {
  jelly:{name:'jelly',age:20},
  mary:{name:'mary',age:25}
} ={}

const weakPeople=new WeakSet([jelly,mary])
console.log(weakPeople)
mary=null
console.log(weakPeople) 

// mary 這個屬性值就不見了, 若是用數組來存儲,這個值仍是存在的
  • 應用:單例屬性,引用的追蹤

31.map

  • 能夠和數組同樣進行循環和遍歷
  • 能夠和set同樣使用相相似的api
const people = new map();
 people.set('jelly',23)
 people.has('jelly')    //檢驗是否含有jelly這個值
 people.delect('jelly') //進行刪除
 people.clear()所有刪除
 //對 fruits 進行賦值 
 const fruits = new Map([['apple',6],['banana',5]])
 
 //用forEach和解構的方式來遍歷map
 fruits.forEach([key,value]=>{
  console.log(key,value)   
 })
 //若是不用解構方式,他返回的值是一整個是數組
  • 應用場景: 存儲對象的信息,而不僅僅是這個對象

32.weakMap

  • 和weakSet 相似不能進行循環,也沒有clear方法,沒有size
  • 保存的key值只能是對象
  • 防止內存泄漏
const jelly = {name:'jelly'};
 const miffy = {name:'miffy'}

 const strong= new Map();
 const weak=new WeakMap();
 
 strong.set(jelly,'jelly is the best!')
 weak.set(miffy,'miffy is the 2nd best!')
未完待續

  1. 0-9
  2. A-Za-z0-9_
  3. trnvf
相關文章
相關標籤/搜索