標籤:java 使用 io ar cti 代碼 javascript window
函數執行時的範圍鏈和使用中的物件是如何形成的及與閉包的關係
1、javascript解析器啟動時就會初始化建立一個全域對象global object,這個全域對象就 擁有了一些預定義的全域變數和全域方法,如Infinity, parseInt, Math,所有程式中定義的全域變數都是這個全域對象的屬性。在用戶端javascript中,Window就是這個javascript的全域對象。
2、當javascript執行一個function時,會產生一個對象,稱之為call object,function中的局部變數和function的參數都成為這個call object的屬性,以免覆寫同名的全域變數。
3、javascript解析器每次執行function時,都會為此function建立一個execution context執行環境,在此function執行環境中最重要的一點就是function的範圍鏈scope chain,這是一個對象鏈,由全域對象和使用中的物件構成,對象鏈具體構成過程見下面說明。
4、標識的尋找機制:當javascript查詢變數x的值時,就會檢查此範圍鏈中第一個對象,可能是function的call object或全域對象(比如window),如果對象中有定義此x屬性,則傳回值,不然檢查範圍鏈中的下一個對象是否定義x屬性,在範圍鏈中沒有找到,最後返回undefined。
5、當javascript執行一個function時,它會先將此function定義時的範圍作為其範圍鏈,然後建立一個使用中的物件(call object),置於範圍鏈的頂部,function的參數及內部var聲明的所有局部變數都會成為此調用對象的屬性。
6、this關鍵詞指向方法的調用者,而不是以調用對象的屬性存在,同一個方法中的this在不同的function調用中,可能指向不同的對象。
7、The Call Object as a Namespace。將使用中的物件當作命名空間使用,避免命名汙染。
(function() {
// 在方法體內用var聲明的所有局部變數,都是以方法調用時建立的活對象的屬性形式 存在。
// 這樣就避免與全域變數發生命名衝突。
})();
8、javascript中所有的function都是一個閉包,但只有當一個嵌套函數被匯出到它所定義的範圍外時,這種閉包才強大。如果理解了閉包,就會理解function執行時的範圍鏈和使用中的物件,才能真正掌握javascript。
9、嵌套閉包的微觀世界:在嵌套閉包時,當內建函式的引用被儲存到嵌套閉包之外一個全域變數或者一個對象的屬性時,在這種情況下,此內建函式有一個外部參考,並且在其外圍調用函數的使用中的物件中有一個屬性指向此內建函式。因為有其他對象引用此內建函式,所以在外圍函數被調用一次後,其建立的使用中的物件會繼續存在,並不會被記憶體回收行程回收(因為引用計數不為0),內建函式的參數和局部變數都會在這個使用中的物件中得以維持,javascript代碼任何形式都不能直接存取此使用中的物件,但是此使用中的物件是內建函式被調用時建立的範圍鏈的一部分,可以被內建函式訪問並修改。