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