要了解清楚js中的閉包制機,那么得先了解全局執行環境、塊級執行環境、函數執行環境、變量對象、環境棧、作用域鏈、摧毀執行環境。
全局執行環境
全局執行環境指的是最外層的執行環境。在web中全局執行環境被認為window對象,所以你在全局環境中創建的變量與函數都是對象的屬性和方法。
函數執行環境
函數執行環境指的是函數體。
塊級執行環境
塊級執行環境指的是塊級定義區域。
'use strict';
// 全局執行環境
// .....
{
// 塊級執行環境
// 代碼 ....
}
function func() {
// 函數執行環境
//...
}
變量對象
每一個執行環境最有一個與之關聯的變量對象,變量對象中存儲當前環境中定義的變量與函數。在使用變量或函數時,都是在個變量對象上去尋找成員的。這個對象是無法訪問的,但是你可以在作用域鏈[scope]中查看到所定義的成員(如果沒有使用的話可能無法看到,這和優化有關)。
環境棧
每個函數或塊都有自己的執行環境。當執行流進入一個函數時,函數的環境就會被推入“環境棧”中。函數執行完后,棧將其彈出並銷毀變量對象,然后把控制權返回在給之前的執行環境。如果內執行環境的變量對象,被外部執行環境引用,那么內部環境變量對象就無法被銷毀(如:閉包)。
作用域鏈
作用域鏈是一個列表,存儲着與執行環境相關的變量對象,通過【scope】屬性可查看變量對象列表。
關系圖

實例講解
// 例子1:常見的函數嵌套
'use strict';
function a() {
let x = 2;
return function() {
return x;
}
}
let func = a(); // 返回a函數體內的 匿名函數
console.log(func()); // 在全局執行環境中,訪問a函數內部變量。 如果是非閉包函數,那么執行完后
我們來看一下,a函數體內匿名函數的作用域鏈。

[Scopes] : 是當前匿名函數的作用域鏈。
索引為 0 的:是a函數的執行環境的變量對象, x 表示 變量對象中的。
索引為 1 的:全局執行環境變量對象。
// 例子2:訪問塊內部變量
1:返回塊級內容函數 實現在全局執行環境中訪問塊級內容變量。
'use strict';
let func = null;
{
let x = "你好";
func = function () {
return x;
}
}
// 返回塊級內容函數 實現在全局執行環境中訪問塊級內容變量。
console.log(func());
作用域鏈圖:

我的百度經驗地址:https://jingyan.baidu.com/article/adc81513c23327f722bf7358.html
