談一談閉包

2022-06-22 21:42:17 字數 2749 閱讀 5240

1. 前景知識

變數物件:每乙個函式執行的時候都會用 引數、區域性變數來生成自己的變數,這種叫 ao。全域性的變數物件是是 window,叫 go。

作用域鏈生成:

定義函式的時候:定義函式時所在的執行環境也有乙個作用域鏈,這個作用域鏈會被儲存在函式的內部[[scope]]屬性。比如,我們在全域性定義乙個函式 a,在 a 裡定義乙個函式 b, a 的作用域鏈是:a.ao --> window,所以b.[[scope]] = a.ao --> window

執行函式的時候:會建立自己的 ao 物件,然後複製[[scope]] 並把自己的 ao 放到 [[scope]] 最前端作為自己的作用域鏈:b.作用域鏈 = b.ao --> a.ao --> window

作用域鏈本質上是乙個指向變數物件的指標列表,它只包含引用但不實際包含變數物件。

函式執行完畢後,它的作用域鏈一定會被銷毀,但是它的作用域鏈上引用的變數物件不一定會被銷毀(閉包)

2. 什麼是閉包

閉包的概念很簡單,就是指有權訪問另乙個函式作用域中的變數的函式

我們來分析乙個例子:

let test = ()=>;

})();

fun(); // 1

}test();

test = null;

我們把上面例子的匿名函式都起乙個名字,然後我們可以得到函式 fun 的作用域鏈是長這個樣子的:fun.ao --> a.ao --> test.ao --> window,所以,根據作用域鏈的先後關係,最後的輸出結果就是 1

閉包理解起來其實不難,但是要想更深入理解閉包的原理,那麼就得從變數物件入手。

我們都知道,正常執行完畢乙個函式後,這個函式裡面的變數外部是訪問不了的了,從**層面去看是我們沒有指標去訪問裡面的變數,但從記憶體層面看,是這個函式的作用域鏈、變數物件都被瀏覽器進行銷毀**了。當然,閉包是例外,閉包作用域鏈上的各級函式ao物件肯定沒被銷毀,那麼為什麼它們沒有被銷毀呢

瀏覽器的記憶體**是另乙個大問題,這裡我們不深入細究,我們知道一點就行:乙個物件如果沒有任何指標變數去引用它,那麼瀏覽器就會去嘗試**它

ok,那我們逆推就可以知道,閉包作用域鏈上的各級函式ao物件之所以能被儲存下來沒被**,就是因為它們還在被引用。被誰引用?就是被閉包作用域鏈引用啊。

所以,我們再分析上面的閉包**,我們可以得知這樣的流程:

執行函式 test,生成test.aotest.作用域鏈

執行函式 a,生成a.aoa.作用域鏈

定義函式 fun,fun.[[scope]] = a.ao --> test.ao --> window

函式 a 執行完畢,a 被銷毀,a.作用域鏈也被銷毀,a.aofun.[[scope]]引用沒被銷毀

執行 fun,生成 ·fun.aofun.作用域鏈 = fun.ao --> a.ao --> test.ao --> window

函式 fun 執行完畢,函式 fun 還被 fun 指標引用沒被銷毀,fun.作用域鏈被銷毀,fun.作用域鏈上引用的fun.ao, a.ao被銷毀,test.aowindow因為還有被其他指標引用所以沒被銷毀。

函式 test 執行完畢,函式 test 還被 test 指標引用沒被銷毀,test.作用域鏈被銷毀,test.作用域鏈上引用test.ao被銷毀,test.ao裡的函式 fun 也被銷毀。

test = null,函式 test 被銷毀 。

這也就是前面說的,函式執行完畢後,它的作用域鏈一定會被銷毀,但是它的作用域鏈上引用的變數物件不一定會被銷毀,因為可能被return的閉包的作用域鏈引用。

所以,閉包的本質是,閉包父函式的變數物件一直被閉包的作用域鏈引用著無法被瀏覽器**。所以哪怕父函式執行完畢之後依舊可以通過閉包去訪問父函式變數物件裡的變數。

看一道題目:

let b = 1;

let fun1 = ()=>

}let back = fun1();

let fun2 = (back)=>

fun2(back);

通過分析可知,back 函式的作用域鏈是back.ao --> fun1.ao --> window,所以 back() 可以正常列印 a=1,b=1,但是列印 c 就會報錯的,因為在它的作用域鏈的變數物件上不存在 c 這個變數。

所以發現沒有,雖然 back 函式是在 fun2 裡面呼叫的,但是 back 的作用域鏈卻沒有包含 fun2 的變數物件。因為,乙個函式的作用域鏈的範圍其實在函式定義的時候就已經決定了,函式執行時能決定的只是作用域鏈最前端的一部分而已。

談一談教育

今晚和研究生的師兄聊了會天,突然就說到教育的問題,有點感想,就寫下來,算是我對中國教育的一點看法吧。毫無疑問,中國的教育體制存在不少問題。在高中的時候或許還不是那麼明顯 對比起大學來說 上了大學,我才看清了我們教育的一些弊端。我覺得,最大的弊端,在於價值觀的引導問題上。不知道大家有沒和我一樣覺得當今...

談一談裁員

資本寒冬,經濟不景氣,要保持公司運作,可能會涉及到裁員。另外,有些員工的價值觀已經與公司不符,再留用可能會影響團隊和公司的和諧,此時也可能會涉及到裁員。裁員,不是說想裁就能裁的,需要考慮幾個方面 為什麼要裁?是否可以不裁?裁員是否會影響業務程序?裁員是否會付出經濟代價 賠償 裁員是否會負一定的法律責...

談一談揹包問題之動態規劃

揹包問題簡言之就是給定乙個最大容量求其能裝下的最大價值,長話短說,先給是揹包問題的偽 如下 01揹包問題 for int i 0 i v w 每一件物品的價值和容量 for int j sumw j w j 完全揹包問題 for int i 0 i v w 每一件物品的價值和容量 for int j...