天天看點

JS閉包的了解

文章目錄

  • ​​閉包的簡介:​​
  • ​​閉包的定義:​​
  • ​​閉包的特點:​​
  • ​​閉包的作用:​​
  • ​​閉包的構成:​​
  • ​​應用場景:​​
  • ​​拓展:​​
  • ​​簡單demo:​​
  • ​​閉包的缺點:​​

閉包的簡介:

閉包就是能夠讀取其他函數内部變量的函數。隻有函數内部的子函數才能讀取局部變量,在本質上,閉包是函數内部和函數外部連接配接起來的橋梁。

當函數可以記住并通路所在詞法作用域時,就産生了閉包,即使函數是在目前詞法作用域之外執行。 - - 出自《你不知道的JavaScript(上卷)》

閉包的定義:

如果在一個内部函數裡,對在外部作用域(但不是全局作用域)的變量進行引用,那麼内部函數就被認為是閉包(closure)。

閉包的特點:

  1. 可以讀取自身函數外部的變量(沿着作用域鍊尋找)先從自身開始查找,如果自身沒有才會繼續往上級查找,自身如果擁有将直接調用。(哪個離的最近就用哪一個)
  2. 延長内部變量的生命周期
  3. 函數b嵌套在函數a内部
  4. 函數a傳回函數b

閉包的作用:

在函數a執行完并傳回後,閉包使得JavaScript的垃圾回收機制不會收回a所占用的資源,因為a的内部函數b的執行需要依賴a中的變量,閉包需要循序漸進的過程。

閉包的構成:

閉包由倆個部分構成:

  • 函數
  • 以及建立該函數的環境

應用場景:

  1. 保護函數内的變量安全。函數a中隻有函數b才能通路,而無法通過其他途徑通路到,是以保護了i的安全性。
  2. 在記憶體中維持一個變量

了解JAVA的同學肯定知道JAVA是有私有方法的。私有方法隻能被一個類中的其他方法所調用,但是JavaScript并沒有,是以就需要用閉包來模拟。

私有方法有利于限制對代碼的通路,可以避免非核心的方法幹擾代碼的公共接口,減少全局污染。

​demo:​

var test = (function() {
  var a = 1;
  function add(val){
    a += val;
  }
  return {
    add1() {
      add(1);
    },
    add2() {
      add(2);
    },
    result() {
      return a;
    }
  }
})();      

上面這種方式也叫做子產品模式(module pattern)。

關于設計模式請看 ​

拓展:

回收機制:

在JavaScript中,如果一個對象不再被引用,那麼這個對象就會被GC回收。如果倆個對象互相引用,而不再被第3者所引用,那麼這倆個互相引用的對象也會被回收。因為函數a被b引用,b又被a外的c引用,這就是為什麼函數a執行後不會被回收的原因。

簡單demo:

var num = 6;
function outer() {
  var num = 1;
  function inner() {
    var n = 2;
    alert(n + num);
  }
  return inner
}
const test = outer();
test();      
JS閉包的了解

結果與我們想的一樣,是3。

閉包的缺點: