作用域鏈(scope chain)
理解:
1.函數(shù)在執(zhí)行的過(guò)程中,先從自己內(nèi)部找變量
2.如果找不到抓督,再?gòu)膭?chuàng)建當(dāng)前函數(shù)所在的作用域去找, 以此往上
3.注意找的是變量的當(dāng)前的狀態(tài)
作用域鏈決定了哪些數(shù)據(jù)能被函數(shù)訪問(wèn)。當(dāng)一個(gè)函數(shù)創(chuàng)建后束亏,它的作用域鏈會(huì)被創(chuàng)建此函數(shù)的作用域中可訪問(wèn)的數(shù)據(jù)對(duì)象填充铃在。
當(dāng)某個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境及相應(yīng)的作用域鏈枪汪。然后涌穆,使用arguments和其他命名參數(shù)的值來(lái)初始化函數(shù)的活動(dòng)對(duì)象。但在作用域鏈中雀久,外部函數(shù)的活動(dòng)對(duì)象始終處于第二位宿稀,外部函數(shù)的外部函數(shù)對(duì)象處于第三位……直至作為作用域終點(diǎn)的全局執(zhí)行環(huán)境
作用域鏈的前端始終是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象。如果這個(gè)環(huán)境是函數(shù)赖捌,則將其活動(dòng)對(duì)象作為變量對(duì)象祝沸。活動(dòng)對(duì)象在最開(kāi)始時(shí)只包含一個(gè)變量越庇,即arguments對(duì)象罩锐。作用域鏈的下一個(gè)變量對(duì)象來(lái)自包含環(huán)境,而在下一個(gè)變量對(duì)象則來(lái)自下一個(gè)包含環(huán)境卤唉。這樣一直延續(xù)到全局執(zhí)行環(huán)境涩惑;全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象。
這里面有很多概念桑驱,比如什么是執(zhí)行環(huán)境竭恬、變量對(duì)象等。
執(zhí)行環(huán)境(Execution Context)
執(zhí)行環(huán)境是JavaScript中的重要概念之一熬的。執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問(wèn)的其他數(shù)據(jù)痊硕,決定了他們各自的行為。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象押框,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中岔绸。
全局執(zhí)行環(huán)境是最外圍的一個(gè)執(zhí)行環(huán)境。在Web瀏覽器中橡伞,全局執(zhí)行環(huán)境被認(rèn)為是window對(duì)象盒揉,因此所有全局變量和函數(shù)都是作為window對(duì)象的屬性和方法創(chuàng)建的。某個(gè)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后兑徘,該環(huán)境被銷毀预烙,保存在其中的所有變量和函數(shù)定義也隨之銷毀(全局執(zhí)行環(huán)境知道應(yīng)用程序退出–例如關(guān)閉網(wǎng)頁(yè)或?yàn)g覽器—時(shí)才會(huì)被銷毀)
每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí)道媚,函數(shù)的環(huán)境就會(huì)被推入一個(gè)環(huán)境棧中扁掸。而在函數(shù)執(zhí)行后翘县,棧將其環(huán)境彈出,把控制權(quán)返回給之前的執(zhí)行環(huán)境谴分。
執(zhí)行環(huán)境的建立分為兩個(gè)階段:進(jìn)入執(zhí)行上下文(創(chuàng)建階段)和執(zhí)行階段(激活/執(zhí)行階段)
(1)進(jìn)入上下文階段:發(fā)生在函數(shù)調(diào)用時(shí)锈麸,但在執(zhí)行具體代碼之前。具體完成創(chuàng)建作用域鏈牺蹄;創(chuàng)建變量忘伞、函數(shù)和參數(shù)以及求this的值
(2)執(zhí)行代碼階段:主要完成變量賦值、函數(shù)引用和解釋/執(zhí)行其他代碼
總的來(lái)說(shuō)可以將執(zhí)行上下文看作是一個(gè)對(duì)象
變量對(duì)象(Variable Object)
每一個(gè)執(zhí)行環(huán)境都對(duì)應(yīng)一個(gè)變量對(duì)象沙兰,在該執(zhí)行環(huán)境中定義的所有變量和函數(shù)都存放在其對(duì)應(yīng)的變量對(duì)象中氓奈。
(1)進(jìn)入執(zhí)行上下文時(shí),VO的初始化過(guò)程如下:
函數(shù)的形參:變量對(duì)象的一個(gè)屬性鼎天,其屬性名就是形參的名字舀奶,其值就是實(shí)參的值;對(duì)于沒(méi)有傳遞的參數(shù)斋射,其值為undefined育勺;
函數(shù)聲明:變量對(duì)象的一個(gè)屬性,其屬性名和屬性值都是函數(shù)對(duì)象創(chuàng)建出來(lái)的罗岖,如果變量對(duì)象已經(jīng)辦好了相同名字的屬性涧至,則替換它的值
變量聲明:變量對(duì)象的一個(gè)屬性,其屬性名即為變量名桑包,其值為undefined南蓬;如果變量名和已經(jīng)聲明的函數(shù)名或者函數(shù)的參數(shù)名,則不會(huì)影響已經(jīng)存在的屬性
(2)執(zhí)行代碼階段哑了,變量對(duì)象中的一些屬性u(píng)ndefined值將會(huì)確定