js 预编译 解释执行 作用域链 闭包
?
預編譯與解釋執行?
頁面產生時創建全局對象window對象,同時創建document、history、 location、navigator、screen等屬性。
腳本文件加載完后,分析語法是否合法。
開始預編譯
(1)查找變量聲明,作為window屬性,并且值為undefined
(2)查找函數聲明,作為window屬性,值為函數體
上面js預編譯后的window對象:
window = {//頁面加載創建window時,添加的屬性 a: undefined,b: undefined,d: undefined,c: function c(x){var aa = 2;function d(){var ab = 3;}} }預編譯后,從上到下解釋執行
window.b = 1;
window.d = function(){
//...
}
執行c(10)
解釋執行后的window對象:
window = {//頁面加載創建window時,添加的屬性 a: undefined,b: 1,d: function(){//...},c: function c(x){var aa = 2;function d(){var ab = 3;}} }?
作用域與閉包(函數c的創建與執行)
在js文件預編譯時,創建c函數,函數c在創建的過程中,創建了一個內部屬性[[scope]],即該函數的作用域鏈,作用域鏈是作用域對象的集合。
?
在執行函數c時,首先預編譯處理,創建一個執行上下文對象(execute context),即一個函數運行時的環境。執行上下文對象有它自己的作用域鏈(scope chain)。在上下文對象創建時,初始化它的作用域鏈。首先把c.scope賦值給context.scope,然后創建一個活動對象(Active Object),并且把活動對象放在context作用域鏈的最前端。
AO(活動對象)創建:
(1)查找形參和變量聲明,賦值為undefined
(2)實參值傳給行參
(3)查找函數聲明,賦值函數體
在函數執行時,訪問數據的權限,從作用域鏈從上往下查找。
在函數c執行時,函數內部的函數d創建,在創建過程中d有一個自己的作用域鏈。作用域鏈指向的對象與c的上下文執行環境的作用域鏈分別指向相同的對象。
當函數C執行完后,執行上下文對象銷毀。由于AO對象被函數d的scope引用,則AO對象不能被銷毀。若函數d沒有被銷毀(如函數d作為返回函數被全局變量引用),AO對象一直存儲在內存中。
閉包:一個函數內嵌套一個函數,嵌套的函數未被釋放時,外部函數內的變量不能釋放。
如:
function A(){
var a = 1;
function B(){
var b = 2;
? ? ? ?}
return B;
}
var b = A();
分析:函數A執行后,由于函數內部的嵌套函數被全局變量b引用,即函數B不能被釋放。又函數B的作用域鏈引用了函數A的AO對象,所以函數A內的變量的內存不能被回收。
?
轉載于:https://www.cnblogs.com/fe-huahai/p/6433270.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的js 预编译 解释执行 作用域链 闭包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring MVC 异步处理请求,提高
- 下一篇: CCF201409-5 拼图(30分)