原文地址:深入理解閉包(一)——鋪墊
前兩天寫了一篇關(guān)于作用域和作用域鏈的文章,還自以為理解透了,這兩天一直在琢磨閉包,才發(fā)現(xiàn)我之前對作用域和作用域鏈的理解簡直不忍直視沼溜,甚至那個時候我還以為執(zhí)行上下文跟作用域是同一個東西,哇現(xiàn)在真想死一死游添∠挡荩看了那么多講閉包的文章之后我也得出一個經(jīng)驗,一篇文章是講不清閉包的唆涝,因為你需要理解的不僅僅是閉包找都,還有前面需要鋪墊的很多知識,所以我打算寫一個系列文廊酣,今天我就先回憶一些基礎(chǔ)知識能耻。
堆與棧
堆與棧是兩種數(shù)據(jù)結(jié)構(gòu),棧在javascript的執(zhí)行上下文中有重要體現(xiàn)亡驰,因此我們有必要去弄懂它晓猛。
堆
堆的存取方式比較靈活,程序員為數(shù)據(jù)分配空間進行存儲凡辱,引用數(shù)據(jù)時只需要知道數(shù)據(jù)存在了那個地址就可以使用戒职,就像是我們?nèi)D書館找一本書,只需要知道這本書的編號就能知道書的位置煞茫,找到對應(yīng)的書架找到想要的書帕涌。
棧
棧的存取方式遵循先進后出原則。如上圖:存儲數(shù)據(jù)時续徽,1最先入棧,4最后入棧亲澡;使用數(shù)據(jù)時钦扭,4最先出棧,1最后出棧床绪。大家都打過羽毛球吧客情,裝羽毛球的長筒就類似于這個棧,桶口就一個癞己,我們每次只能拿出最上面的那個球膀斋,要想拿出下面的球就必須把它上面的都拿出來。
數(shù)據(jù)的基本類型和引用類型
基本數(shù)據(jù)類型
基本類型值指的是簡單數(shù)據(jù)段,JavaScript中有5中基本數(shù)據(jù)類型痹雅,分別是Undefined仰担、Null、Boolean绩社、Number摔蓝、String赂苗。基本數(shù)據(jù)類型是按值訪問,如果從一個變量向另一個變量復(fù)制基本類型的值贮尉,會在變量對象上創(chuàng)建一個新值拌滋,把該值復(fù)制到為新變量分配的位置上。
舉個栗子:
var num1 = 5;
var num2 = num1;
num1中保存的值是5猜谚,又定義一個變量num2败砂,并用num1的值來初始化它,那么num1的5就復(fù)制給了num2魏铅,但這兩個5是互相獨立的昌犹,誰都不影響誰,即使你改變了其中一個的值沦零,另外一個也不會受到影響祭隔。
引用數(shù)據(jù)類型
引用類型值指的是那些可能由多個值構(gòu)成的對象,如數(shù)組路操。引用數(shù)據(jù)類型是按引用訪問的疾渴,當一個變量向另一個變量復(fù)制引用類型值的時候,復(fù)制的不是一個值而是一個指向這個值的指針屯仗,復(fù)制操作結(jié)束后搞坝,兩個變量實際上將引用同一個對象,因此改變其中一變量魁袜,另一個也隨之改變桩撮。
舉個栗子:
var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"
首先,變量obj1保存了一個對象的新實例峰弹,然后這個值被復(fù)制到了obj2中店量,此時它們都指向同一個對象,因此當我們給obj1添加name屬性后鞠呈,可以通過obj2來訪問這個屬性融师,如果你還不理解,那么你看完下圖就會了然了蚁吝。
下面我們看兩個小測試來檢測一下自己對上面內(nèi)容的理解
var a = 10;
var b = a;
b = 30;
console.log(a); //10
var m = { a: 10, b: 20 }
var n = m;
n.a = 30;
console.log(m.a); //30
垃圾回收機制
函數(shù)中局部變量經(jīng)歷一個生命周期:
- 當我們定義一個變量時旱爆,會為它分配一個內(nèi)存空間用來儲存變量的值
- 當我們讀取或使用這個變量時,會使用它的內(nèi)存空間
- 使用完畢時會釋放內(nèi)存空間
上面生命周期的最后一步窘茁,其實就是垃圾回收怀伦。JavaScript有自動垃圾收集機制,就是找出那些不再繼續(xù)使用的值山林,然后釋放其占用的內(nèi)存房待,那么怎么判斷什么值不再使用呢,一般來說,當一個函數(shù)執(zhí)行完畢吴攒,那么這個局部作用域內(nèi)的變量就沒有存在的必要了张抄,它的內(nèi)存空間就會釋放,但是有一種情況可以阻止這一進程洼怔,那就是——閉包署惯。
javascript代碼執(zhí)行過程
這個流程圖是javascript代碼執(zhí)行要經(jīng)歷的一個完整過程,其中我標出了作用域镣隶,執(zhí)行上下文极谊,作用域鏈,即使你現(xiàn)在還不明白這個流程圖的每個部分都是做什么的安岂,但是你現(xiàn)在至少應(yīng)該明白這三者是完全不一樣的概念轻猖。