本文主要講圍繞JS的執(zhí)行環(huán)境棧進(jìn)行講解,在講解環(huán)境棧前先會(huì)提及棧內(nèi)存和堆內(nèi)存!希望各位看客多多指點(diǎn)!
?首先JavaScript中的變量分為基本類型和引用類型?;绢愋途褪潜4嬖跅?nèi)存中的簡(jiǎn)單數(shù)據(jù)段,而引用類型指的是那些保存在堆內(nèi)存中的對(duì)象。
js 棧 內(nèi)存 和 堆 內(nèi)存
?首先JavaScript中的變量分為基本類型和引用類型?;绢愋途褪潜4嬖跅?nèi)存中的簡(jiǎn)單數(shù)據(jù)段,而引用類型指的是那些保存在堆內(nèi)存中的對(duì)象。
1、基本類型?
?????????基本類型有Undefined、Null、Boolean、Number 和String。這些類型在內(nèi)存中分別占有固定大小的空間,他們的值保存在棧空間,我們通過(guò)按值來(lái)訪問(wèn)的。 ? ? ? ? ? ? ?
2、引用類型
? ? ? ? ? ?引用類型,值大小不固定,棧內(nèi)存中存放地址指向堆內(nèi)存中的對(duì)象。是按引用訪問(wèn)的。如下圖所示:棧內(nèi)存中存放的只是該對(duì)象的訪問(wèn)地址,在堆內(nèi)存中為這個(gè)值分配空間。由于這種值的大小不固定,因此不能把它們保存到棧內(nèi)存中。但內(nèi)存地址大小的固定的,因此可以將內(nèi)存地址保存在棧內(nèi)存中。 這樣,當(dāng)查詢引用類型的變量時(shí), 先從棧中讀取內(nèi)存地址, 然后再通過(guò)地址找到堆中的值。對(duì)于這種,我們把它叫做按引用訪問(wèn)
? ?當(dāng)我們看到一個(gè)變量類型是已知的,就分配在棧里面,比如INT,Double等。其他未知的類型,比如自定義的類型,因?yàn)橄到y(tǒng)不知道需要多大,所以程序自己申請(qǐng),這樣就分配在堆里面。基本類型大小固定,引用類型大小不固定,分開(kāi)存放使得程序運(yùn)行占用內(nèi)存最小。
3、棧內(nèi)存:存放基本類型。 堆內(nèi)存:存放引用類型(在棧內(nèi)存中存一個(gè)基本類型值保存對(duì)象在堆內(nèi)存中的地址,用于引用這個(gè)對(duì)象。)
4、基本類型在當(dāng)前執(zhí)行環(huán)境結(jié)束時(shí)銷毀,而引用類型不會(huì)隨執(zhí)行環(huán)境結(jié)束而銷毀,只有當(dāng)所有引用它 (注意這個(gè)重點(diǎn))
的變量不存在時(shí)這個(gè)對(duì)象才被垃圾回收機(jī)制回收。
JavaScript 執(zhí)行環(huán)境棧
在了解什么是執(zhí)行環(huán)境棧前,我們先需要了解什么是 棧?
棧(stack)又名堆棧 !?
我們可以把他想象成一個(gè)容器, 他的棧底是被封死的,只有一個(gè)出口即只能從棧頂 出來(lái)! 這個(gè)就和他的兄弟 隊(duì)列 有明顯的不同了!

好的了解了棧的出棧入棧規(guī)則,我們繼續(xù)嘮!
我們已經(jīng)知道,當(dāng)瀏覽器第一次加載你的script,它默認(rèn)的進(jìn)了全局執(zhí)行環(huán)境 (a1)。如果在你的全局代碼中你調(diào)用了一個(gè)函數(shù) (a2),那么順序流就會(huì)進(jìn)入到你調(diào)用的函數(shù)當(dāng)中,創(chuàng)建一個(gè)新的執(zhí)行環(huán)境并且把這個(gè)環(huán)境添加到執(zhí)行棧的頂部。
如果你在當(dāng)前的函數(shù) ?(a2) 中調(diào)用了其他函數(shù) (a3),同樣的事會(huì)再次發(fā)生。執(zhí)行流進(jìn)入內(nèi)部函數(shù),并且創(chuàng)建一個(gè)新的執(zhí)行環(huán)境,把它添加到已經(jīng)存在的執(zhí)行棧的頂部。瀏覽器始終執(zhí)行當(dāng)前在棧頂部的執(zhí)行環(huán)境。一旦函數(shù) ( a3 ) 完成了當(dāng)前的執(zhí)行環(huán)境,它就會(huì)被彈出棧的頂部, 把控制權(quán)返回給當(dāng)前執(zhí)行環(huán)境的下個(gè)執(zhí)行環(huán)境 (a2)。下面例子展示了一個(gè)遞歸函數(shù)和該程序的執(zhí)行棧;
?總:
????如上所述,當(dāng)執(zhí)行流進(jìn)入函數(shù)內(nèi)部時(shí)會(huì)創(chuàng)建一個(gè)新的執(zhí)行環(huán)境,在這個(gè)執(zhí)行環(huán)境中申明的變量 ,便保存在棧內(nèi)存中,當(dāng)函數(shù)被彈出來(lái)時(shí), 這個(gè)函數(shù)的棧內(nèi)存被會(huì)被銷毀( 不考慮閉包的情況 )!