最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

JavaScript基礎(chǔ) 理解閉包

2021-01-14 14:05 作者:刂C刂C刂  | 我要投稿

定義: 如果一個作用域可以訪問另外一個函數(shù)的局部變量,此時就形成了閉包。而被訪問變量的這個函數(shù)就是閉包。


理解閉包前,先看看自己是否理解以下幾點概念:

1.首先明確: 閉包是函數(shù)?。。?/p>

2.js的兩種數(shù)據(jù)類型:簡單數(shù)據(jù)類型(number,布爾,null,string ,undefined); ?復(fù)雜數(shù)據(jù)類型(對象,數(shù)組,函數(shù))。


問:這兩種數(shù)據(jù)類型如何區(qū)分出來的?

答: 其根本原因是在內(nèi)存中的存儲方式不同!


簡單數(shù)據(jù)類型直接存儲在中,比如: var i = 10; 10這個值存放在棧中,代碼運行時直接就可以拿到。

復(fù)雜數(shù)據(jù)類型的值存儲在中,棧中存放的是指向堆中數(shù)據(jù)的地址。

比如: var a = { n: 100}; ?代碼運行時,在棧中實際存放的是 a = AABBBFFF123 的一串指向堆的地址,而真正的值 n: 100 ,是存放在堆中的。調(diào)用 對象a 時,實質(zhì)上是依靠棧中存儲的這段地址,去引用堆中的值。

值傳遞

3.js代碼的垃圾回收及內(nèi)存管理:

  1. 局部作用函數(shù)的局部變量,只在局部作用域可以訪問。

  2. 全局作用域的變量,無論全局還是局部,都可以訪問。

  3. 當期嵌套的作用域鏈的其他函數(shù)的變量和參數(shù)。(這就是閉包的實現(xiàn)原理)

    以上3種情況下,其存儲變量和參數(shù)的內(nèi)存空間都不回收。

舉個例子:?

function fn() {

? ? ?var i = 10;

}

fn(); // 函數(shù)執(zhí)行完畢,局部變量 i 占用的內(nèi)存空間被回收

console.log(i); ?// undefined


理解以上,下面開始正式理解閉包??聪旅孢@段代碼:

function a() {

? ? var i = 10;

? ? function b() {

? ? ? ? ? return i ;

? ? }

? ? return b();

}

var f = a();

console.log( f() ); // 輸出1

先看結(jié)果: 上面的代碼,我明明是在全局作用域下,卻獲取到了 局部作用域:函數(shù)a()? 中定義的變量 i。為什么?

再來回頭閱讀一遍剛剛提到的js垃圾回收: 當期嵌套的作用域鏈的其他函數(shù)的變量和參數(shù),不回收它的內(nèi)存空間?。。?/strong>


為了幫助理解:下面我們分析整段代碼在內(nèi)存中運行的過程:

代碼執(zhí)行過程

第一步: 變量提升,預(yù)定義函數(shù)。

第二步: f = a();?

—> ?a() 是函數(shù),是復(fù)雜數(shù)據(jù)類型。

—> ?所以我們實質(zhì)上給f 賦的值是一串指向堆中的地址。

假設(shè):函數(shù)a堆地址為: AABBCC133。

? ? ? ?函數(shù)b堆地址為:FFFFBBBXX。


第三步:console.log(f());

—> f();?

—> 由于 f 等價于 執(zhí)行地址為:AABBCC133 的a函數(shù)。

—> 所以 f() 等價于 a()();

—> a() 的返回值,return的是 b(),而實質(zhì)上是return 了一串地址為:FFFFBBBXX 的堆地址。

—> 所以f() 實際上就是:立即執(zhí)行堆地址為

FFFFBBBXX 的函數(shù)。


注意!?。?!以下就是閉包的核心了?。。。?!

看完了全局作用域中的執(zhí)行,我們再看局部作用域:a()?

—> var i = 10;

—> 定義了一個堆地址為:FFFFBBBXX 的函數(shù)b。

—> return b();

—> 函數(shù)a執(zhí)行結(jié)束。

—> 根據(jù)js的垃圾回收機制,一個局部作用域執(zhí)行結(jié)束,就改釋放它所占用的內(nèi)存。

但是?。?!由于 函數(shù)b()預(yù)定義時,使用了函數(shù)a() 定義的變量 i 。所以此時 函數(shù)a 雖然已經(jīng)執(zhí)行完成,return了,但是其占用的內(nèi)存并沒有被釋放。

—> 接著我們在全局作用域下執(zhí)行b函數(shù)。

—> b函數(shù)執(zhí)行完成,b占用的內(nèi)存被釋放。在此時,a函數(shù)占用的內(nèi)存才被釋放。


應(yīng)該非常詳細了,如果還是不理解的話,可能需要仔細回顧js基礎(chǔ):?

1. 堆、棧的相關(guān)概念;

2. js的數(shù)據(jù)類型;

3. js的垃圾回收機制;

照著這個順序來學(xué)習(xí)回顧,然后思考為什么需要閉包,閉包在內(nèi)存中是如何實現(xiàn)的。

JavaScript基礎(chǔ) 理解閉包的評論 (共 條)

分享到微博請遵守國家法律
平江县| 辽源市| 常宁市| 曲沃县| 肃南| 长岭县| 涪陵区| 武安市| 雷山县| 淮滨县| 乐亭县| 宜章县| 巍山| 阜城县| 驻马店市| 景宁| 腾冲县| 咸宁市| 崇文区| 名山县| 读书| 奇台县| 张掖市| 恩平市| 万安县| 勐海县| 昆明市| 万源市| 陕西省| 兴山县| 岳阳市| 于田县| 永州市| 涡阳县| 泰安市| 五莲县| 修武县| 达孜县| 高阳县| 玛多县| 茂名市|