欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理詳解

 更新時(shí)間:2023年01月08日 11:09:11   作者:既白biu  
這篇文章主要介紹了JavaScript函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理的知識(shí),文章內(nèi)容非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在我們平常編寫JavaScript代碼的時(shí)候,難免會(huì)用到函數(shù),函數(shù)里面會(huì)有各種變量,這些變量的作用的范圍,以及在使用內(nèi)存存儲(chǔ)這些變量時(shí),內(nèi)存管理的問題,在平時(shí)編程亦或者面試時(shí),多多少少都會(huì)遇到,所以這篇文章針對這三個(gè)問題,進(jìn)行了深入的探討。

函數(shù)執(zhí)行

首先說一下JavaScript執(zhí)行代碼的順序,JavaScript在執(zhí)行一段可執(zhí)行代碼的時(shí)候,會(huì)創(chuàng)建一個(gè)執(zhí)行上下文棧(Execution Context Stack 簡稱ECStack),執(zhí)行全局代碼時(shí)創(chuàng)建的全局執(zhí)行上下文(Global Execution Context 簡稱GEC),以及執(zhí)行函數(shù)時(shí)創(chuàng)建的函數(shù)執(zhí)行上下文(Function Execution Context 簡稱FEC),在運(yùn)行時(shí)都會(huì)按順序放入棧中,而不管是全局執(zhí)行上下文還是函數(shù)執(zhí)行上下文在創(chuàng)建時(shí)都會(huì)有一個(gè)變量對象(variable Object)。

全局執(zhí)行上下文

在JavaScript執(zhí)行全局代碼時(shí),會(huì)創(chuàng)建一個(gè)全局執(zhí)行上下文,放入執(zhí)行上下文棧,還有一個(gè)GlobalObject(GO),全局執(zhí)行上下文中會(huì)有一個(gè)變量對象(variable Object),指向GO。

在編譯階段,GO會(huì)對在全局定義的變量初始化為undefined,當(dāng)遇到函數(shù)時(shí),便會(huì)以函數(shù)名作為GO的一個(gè)屬性名,值為存儲(chǔ)這個(gè)函數(shù)空間的內(nèi)存地址,在這個(gè)函數(shù)空間中,會(huì)有函數(shù)的執(zhí)行體(代碼段),還會(huì)存儲(chǔ)這個(gè)函數(shù)父級(jí)作用域。

編譯完成后,代碼開始執(zhí)行,便會(huì)對這些變量賦值,當(dāng)然里面除了這些,還有一些全局的對象和函數(shù),比如setTimeout,Date,String等等,還有一個(gè)屬性window賦值為this,當(dāng)遇到函數(shù)時(shí),便會(huì)創(chuàng)建一個(gè)函數(shù)執(zhí)行上下文放入執(zhí)行上下文棧中。

函數(shù)執(zhí)行上下文

上文說到,代碼執(zhí)行時(shí)候,執(zhí)行到函數(shù)時(shí),會(huì)創(chuàng)建函數(shù)執(zhí)行上下文,并且函數(shù)執(zhí)行上下文放入執(zhí)行上下文棧中,同樣,在函數(shù)執(zhí)行上下文里面,會(huì)有一個(gè)VO(Variable Object)變量對象,這里的VO其實(shí)指向AO(Activation Object),這里的AO類似于GO,只不過它不是全局的,而是函數(shù)特有的,在執(zhí)行函數(shù)內(nèi)部代碼前,即編譯階段,也會(huì)將變量賦值為undefined,如果里面嵌套函數(shù),類似GO,會(huì)以函數(shù)名作為GO的一個(gè)屬性名,值為存儲(chǔ)這個(gè)函數(shù)空間的內(nèi)存地址,在這個(gè)函數(shù)空間中,會(huì)有函數(shù)的執(zhí)行體(代碼段),還會(huì)存儲(chǔ)這個(gè)函數(shù)父級(jí)作用域,然后執(zhí)行時(shí),將變量賦值,如果里面嵌套的函數(shù)被執(zhí)行,也會(huì)創(chuàng)建函數(shù)執(zhí)行上下文,并且這個(gè)函數(shù)執(zhí)行上下文放入執(zhí)行上下文棧中。

作用域鏈

其實(shí)在創(chuàng)建VO對象時(shí),也會(huì)在函數(shù)執(zhí)行上下文中創(chuàng)建作用域鏈,這個(gè)作用域鏈包括,自身的變量對象(VO)和父級(jí)作用域,當(dāng)我們查找一個(gè)變量時(shí),真實(shí)的查找路徑是沿著作用域鏈來查找

這段代碼中,顯然name會(huì)順著作用域鏈查找到“why”,然后顯然在foo 函數(shù)編譯未執(zhí)行階段,m=undefined,然后執(zhí)行,m輸出的應(yīng)該是undefined,如下圖是代碼的執(zhí)行邏輯圖。

這里的message輸出的應(yīng)該是Hello Global,foo函數(shù)在全局初始化時(shí)父級(jí)作用域已經(jīng)為全局了,然后foo函數(shù)執(zhí)行時(shí),找不到message變量便會(huì)去父級(jí)作用域去尋找,也就是全局作用域,所以輸出的是Hello Global,執(zhí)行邏輯圖如下。

上圖的輸出是undefined而不是100,就因?yàn)閒oo函數(shù)在解析時(shí)碰到return var a=100已經(jīng)認(rèn)為定義了一個(gè)a,賦值為undefined,但在執(zhí)行時(shí)卻不會(huì)執(zhí)行到這一步。

這里要提一下,如果變量在定義時(shí),未加任何約束。

比如通常來說定義一個(gè)變量是 var name=“anonymous”,let name="anonymous"如果直接寫成name=”anonymous“,在其他語言中,這肯定會(huì)報(bào)錯(cuò),但是在JavaScript中,允許這種寫法,并且這種寫法定義的變量會(huì)直接加到GO里面。

function foo(){
	var a=b=10
}
foo()
console.log(a,b)

var a=b=10<==>等同于var a=10;b=10;

這樣的話b放入GO中,在全局輸出值為10;而a僅在函數(shù)中被定義,在全局輸出顯然會(huì)報(bào)錯(cuò)。

內(nèi)存管理

不管什么樣的編程語言,在代碼的執(zhí)行過程中都是需要給它分配內(nèi)存的,不同的是某些編程語需要我們自己手動(dòng)的管理內(nèi)存,某些編程語言會(huì)可以自動(dòng)幫助我們管理內(nèi)存:

不管以什么樣的方式來管理內(nèi)存,內(nèi)存的管理都會(huì)有如下的生命周期:

  • 第一步:分配申請你需要的內(nèi)存(申請)
  • 第二步:使用分配的內(nèi)存(存放一些東西,比如對象等) ;
  • 第三步:不需要使用時(shí),對其進(jìn)行釋放;

不同的編程語言對于第一步和第三步會(huì)有不同的實(shí)現(xiàn):

手動(dòng)管理內(nèi)存:比如C、 C++ ,都是需要 手動(dòng)來管理內(nèi)存的申請和釋放的 (malloc和free)

自動(dòng)管理內(nèi)存:比如Java、JavaScript. Python. Swift、 Dart等 ,它們有自動(dòng)幫助我們管理內(nèi)存;

引用計(jì)數(shù)

當(dāng)一個(gè)對象有一個(gè)引用指向它時(shí),那么這個(gè)對象的引用就+1 ,當(dāng)一個(gè)對象的引用為0時(shí),這個(gè)對象就可以被銷毀掉;

這個(gè)算法有一個(gè)很大的弊端就是會(huì)產(chǎn)生循環(huán)引用:

var obj1={info:obj2};
var obj2={info:obj1}

標(biāo)記清除

這個(gè)算法是設(shè)置一個(gè)根對象( root object) ,垃圾回收器會(huì)定期從這個(gè)根開始,找所有從根開始有引用到的對象,對于哪些沒有引用到的對象,就認(rèn)為是不可用的對象;

這個(gè)算法可以很好的解決循環(huán)弓|用的問題;

JS引擎比較廣泛的采用的就是標(biāo)記清除算法,當(dāng)然類似于V8弓|擎為了進(jìn)行更好的優(yōu)化,它在算法的實(shí)現(xiàn)細(xì)節(jié)上也會(huì)結(jié)合一些其他的算法。

以上就是JavaScript函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理詳解的詳細(xì)內(nèi)容,更多關(guān)于函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理的資料請關(guān)注腳本之家其它相關(guān)文章,希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論