目前網(wǎng)上大多數(shù)流行的說法都是基于ECMAScript3版本的解析图筹,并且在面試時問到的大多數(shù)都是ECMAScript3的版本內(nèi)容。但是ECMAScript3終將過去, ECMAScript5必然會成為主流撞蜂,所以最好也理解ECMAScript5甚至包括ECMAScript6以及更好版本的內(nèi)容;事實上在TC39( ECMAScript5 )的最新描述中智末,和ECMAScript5之后的版本又出現(xiàn)了一定的差異谅摄;下面先從ECMAScript3中的概念學習JavaScript執(zhí)行原理,事實上系馆,它們只是在對某些概念上的描述不太一樣送漠,在整體思路上都是一致的。
JavaScript的執(zhí)行過程
這段代碼是如何在js中被執(zhí)行的呢由蘑?
首先JS引擎會在代碼執(zhí)行前闽寡,在堆內(nèi)存中創(chuàng)建一個全局對象叫Global Object (GO),這個對象所有的作用域都可以訪問,里面包含里面會包含Date尼酿、Array爷狈、String、Number裳擎、setTimeout涎永、setInterval等等,還有一個window對象指向自己
執(zhí)行上下文
JS引擎內(nèi)部有個執(zhí)行上下文的棧(Execution Context Stack鹿响,簡稱ECS)羡微,它是用于執(zhí)行代碼的調(diào)用棧(注意這個不是物理意義上的棧,是邏輯層面的惶我,只是說執(zhí)行代碼的邏輯像個棧)
現(xiàn)在它要執(zhí)行我們的全局代碼塊妈倔,首先全局代碼快會為了執(zhí)行創(chuàng)建一個執(zhí)行上下文Global Execution Context(GEC),執(zhí)行上下文會被放到ECS里绸贡,GEC被放入到ECS中里面包含兩部分內(nèi)容
1.在代碼執(zhí)行前盯蝴,在parser轉(zhuǎn)成AST的過程中,會將全局定義的量听怕、函數(shù)等加入到GlobalObject中捧挺,但是并不會賦值; 這個過程也稱之為變量的作用域提升(hoisting)
2.在代碼執(zhí)行中尿瞭,對變量賦值松忍,或者執(zhí)行其他的函數(shù);