閉包,一言以蔽之,就是函數和做用域鏈,通俗點就是函數內部使用了外面定義的變量。
咱們從一個例子提及:前端
function foo(){ var a = 2; var b = 3; return function bar(){ console.log(a+b); } } var baz = foo(); baz();
最後的結果,控制檯會輸出a+b的值,也就是5。
在這段代碼裏,出現了閉包,bar()就是函數,bar引用了外面定義的變量a和b。
那麼做用域鏈又是什麼呢?
來個官方解釋:(紅寶書)閉包
當代碼在一個環境中執行時,會建立變量對象的一個做用域鏈。它的做用是保證對執行環境有權訪問的全部變量和函數的有序訪問。它的前端始終都是當前執行代碼所在環境的變量對象。
這些東西看起來好像很難理解。咱們先從執行環境這個概念開始解釋。函數
執行環境(有時也稱做環境)定義了變量或函數有權訪問的其餘數據,決定了它們各自的行爲。spa
好比說上面的例子中,共有三個執行環境:code
bar的局部環境中,沒有變量,可是它能夠訪問foo的局部環境中的變量a和b。
可是在全局環境中不能直接訪問foo的局部環境中的變量a和b。由於全局環境是foo局部環境的父執行環境。對象
最後咱們再來看做用域鏈
下圖能夠形象地表示上面例子的做用域鏈blog
圖中的矩形表示特定的執行環境。內部環境能夠經過做用域鏈訪問全部的外部環境,但外部環境不能訪問內部環境的任何變量或函數。這些環境之間是有次序的。每一個環境能夠向外搜索,但反之不行。圖片