在 JavaScript 中阱高,函數(shù)也是對(duì)象竞端,實(shí)際上屁擅,JavaScript 里一切都是對(duì)象。函數(shù)對(duì)象和其它對(duì)象一樣齐蔽,擁有可以通過(guò)代碼訪問(wèn)的屬性和一系列僅供 JavaScript 引擎訪問(wèn)的內(nèi)部屬性两疚。其中一個(gè)內(nèi)部屬性是 [[Scope]],由 ECMA-262 標(biāo)準(zhǔn)第三版定義含滴,該內(nèi)部屬性包含了函數(shù)被創(chuàng)建的作用域中對(duì)象的集合诱渤,這個(gè)集合被稱為函數(shù)的作用域鏈,它決定了哪些數(shù)據(jù)能被函數(shù)訪問(wèn)谈况。
- 在函數(shù)創(chuàng)建時(shí)勺美,它的作用域鏈中會(huì)填入一個(gè)全局對(duì)象,該全局對(duì)象包含了所有全局變量碑韵。
- 函數(shù)執(zhí)行時(shí)會(huì)創(chuàng)建一個(gè)稱為“運(yùn)行期上下文(execution context)”的內(nèi)部對(duì)象赡茸,運(yùn)行期上下文定義了函數(shù)執(zhí)行時(shí)的環(huán)境。每個(gè)運(yùn)行期上下文都有自己的作用域鏈祝闻,用于標(biāo)識(shí)符解析占卧,當(dāng)運(yùn)行期上下文被創(chuàng)建時(shí),而它的作用域鏈初始化為當(dāng)前運(yùn)行函數(shù)的[[Scope]]所包含的對(duì)象。
- 這些值按照它們出現(xiàn)在函數(shù)中的順序被復(fù)制到運(yùn)行期上下文的作用域鏈中华蜒。它們共同組成了一個(gè)新的對(duì)象辙纬,叫“活動(dòng)對(duì)象(activation object)”,該對(duì)象包含了函數(shù)的所有局部變量叭喜、命名參數(shù)贺拣、參數(shù)集合以及this,然后此對(duì)象會(huì)被推入作用域鏈的前端捂蕴。
- 當(dāng)運(yùn)行期上下文被銷毀譬涡,活動(dòng)對(duì)象也隨之銷毀。
在函數(shù)執(zhí)行過(guò)程中啥辨,每遇到一個(gè)變量涡匀,都會(huì)經(jīng)歷一次標(biāo)識(shí)符解析過(guò)程以決定從哪里獲取和存儲(chǔ)數(shù)據(jù)。該過(guò)程從作用域鏈頭部委可,也就是從活動(dòng)對(duì)象開(kāi)始搜索渊跋,查找同名的標(biāo)識(shí)符,如果找到了就使用這個(gè)標(biāo)識(shí)符對(duì)應(yīng)的變量着倾,如果沒(méi)找到繼續(xù)搜索作用域鏈中的下一個(gè)對(duì)象拾酝,如果搜索完所有對(duì)象都未找到,則認(rèn)為該標(biāo)識(shí)符未定義卡者。函數(shù)執(zhí)行過(guò)程中蒿囤,每個(gè)標(biāo)識(shí)符都要經(jīng)歷這樣的搜索過(guò)程。