天天看點

【前端面經】JS-閉包

1.什麼是閉包?

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

個人了解:閉包就是函數中的函數,裡面的函數可以通路外面函數的變量,外面的變量的是這個内部函數的一部分。

例:其中func_2稱為閉包

function func_1(){
  const n = 10;
  function func_2(){
    console.log(n)
  }
  return func_2
}
           

2.閉包形成的條件

  • 函數嵌套
  • 内部函數引用外部函數的局部變量

3.閉包的記憶體洩露

  • 全局作用域:當網頁關閉時才會銷毀的作用域
  • 私有作用域:隻有函數執行時才會産生的作用域

一般情況下,函數執行會形成一個新的私有作用域,一般函數執行完成後,我們目前作用域都會主動的進行釋放和銷毀。但當遇到函數執行傳回一個引用資料類型的值,并且在函數的外面被某個變量接收了,這種情況下形成的私有作用域都不會銷毀。

💡記憶體洩漏:指任何對象在不被需要之後,它仍然存在。

例:

function fn(){
  var num = 100;
  return function(){}
}
var f = fn() // 此時fn形成的作用域被f接收,不會被銷毀
           

是以閉包不能濫用,否則會導緻記憶體洩漏,影響網頁性能。閉包使用完了之後,要立即釋放資源,将引用變量指向null。

經典面試題:

function outer(){
  var num = 0; // 内部變量
  return function add(){
    num++;
    console.log(num);
  }
}

var func1 = outer();
func1(); // 等同于調用add -> num=1
func1(); // 再次調用 num=2
var func2 = outer();
func2(); // num = 1  重新引用時,生成的作用域也是全新的
func2(); // num = 2
           

4.閉包的作用

  1. 可以讀取函數内部的變量
  2. 可以使變量的值長期儲存在記憶體中,生命周期比較長。但需要及時釋放,否則會影響網頁性能
  3. 可以用來實作Js子產品

5.閉包的運用

  • 防抖節流

總結

閉包就是在函數中定義并傳回另一個函數, 裡層的函數調用外層函數的變量, 進而形成閉包. 而因為外層函數的變量被裡層函數調用, 就會導緻變量不會被垃圾回收機制回收,進而存在記憶體洩漏的風險

繼續閱讀