棧內(nèi)存和堆內(nèi)存
- 棧內(nèi)存:提供了一個(gè)供JS代碼執(zhí)行的環(huán)境
- 全局作用域
- 私有所擁域
- 堆內(nèi)存:存儲(chǔ)引用數(shù)據(jù)類型的數(shù)據(jù)
- 函數(shù)數(shù)據(jù)類型:存代碼字符串
- 對(duì)象數(shù)據(jù)類型:存鍵值對(duì)
內(nèi)存釋放
棧內(nèi)存的形成和釋放
- 全局作用域
- 形成:當(dāng)瀏覽器加載完頁(yè)面的時(shí)候,全局作用域形成
- 銷毀 / 釋放:關(guān)閉頁(yè)面,關(guān)閉瀏覽器,關(guān)閉電腦...
- 私有作用域
- 當(dāng)函數(shù)被調(diào)用的時(shí)候,形成私有作用域
- 銷毀:一般當(dāng)函數(shù)執(zhí)行完成的時(shí)候,私有作用域就釋放了,但是特殊情況除外;
- 不釋放:如果函數(shù)中的東西,被外面的變量或其他的東西占用的時(shí)候,就無(wú)法釋放
- 不立即釋放:最典型的就是當(dāng)函數(shù)執(zhí)行完成的時(shí)候,返回一個(gè)函數(shù)的定義階段,這個(gè)丁一階段,還要再執(zhí)行一次,當(dāng)兩次都執(zhí)行完成的時(shí)候,私有作用域得到釋放;
堆內(nèi)存的形成和釋放
- var obj = {} // 形成
- var fn = function(){} // 形成
- obj = null // 釋放
- fn = null // 釋放
垃圾回收機(jī)制
瀏覽器每隔一段時(shí)間,都會(huì)回收沒(méi)用的內(nèi)存,所以當(dāng)我們不用哪個(gè)地址的時(shí)候,可以把占用這個(gè)地址的東西,執(zhí)行空指針null,這樣,等瀏覽器空閑的時(shí)候,就會(huì)把這個(gè)內(nèi)存進(jìn)行回收;
函數(shù)的定義 3 步驟
- 開辟一個(gè)空間地址
- 把函數(shù)體內(nèi)所有的JS代碼,作為字符串存在這個(gè)空間中
- 把這個(gè)空間地址賦值給函數(shù)名
函數(shù)的調(diào)用 4 步驟
- 形成一個(gè)私有作用域
- 形參賦值
- 預(yù)解釋
- 代碼從上到下執(zhí)行
帶var和不帶var的區(qū)別
- 帶var的:1)私有變量2)會(huì)進(jìn)行預(yù)解釋
- 不帶var的:1)如果是設(shè)置,找不到,window.a = XXX;如果是獲取,找不到,報(bào)錯(cuò)! XXX is not defined;2)不會(huì)進(jìn)行預(yù)解釋
作用域鏈
當(dāng)函數(shù)被調(diào)用的時(shí)候,會(huì)形成一個(gè)私有作用域,看這個(gè)私有作用域中,是否有變量a,
1)如果有,該函數(shù)中所有的a都為私有變量
2)如果沒(méi)有,往上級(jí)查找,一直找到window,還沒(méi)有的話,報(bào)錯(cuò) a is not defined
上級(jí)作用域
- 上級(jí)作用域跟函數(shù)在哪里調(diào)用無(wú)關(guān),只跟函數(shù)隊(duì)形的堆內(nèi)存在哪個(gè)空間下開辟有關(guān);