關鍵字:標識符、執行內容、範圍、範圍鏈、變數對象、使用中的物件理論知識
理解JavaScript如何管理範圍和範圍鏈很重要。因為在範圍鏈中要尋找的變數對象的個數直接影響標識符解析的效能。標識符在範圍鏈中的位置越深,尋找和訪問它所需的時間越長;如果範圍管理不當,就會給指令碼的執行時間帶來負面影響。
當執行JavaScript代碼時,JavaScript引擎會建立一個執行內容(Execution Context)。執行內容(有時被稱為範圍)設定了代碼執行時所處的環境。JavaScript引擎會在頁面載入後建立一個全域的執行內容,然後每執行一個函數時都會建立一個對應的執行內容,最終建立一個執行內容的堆棧,當前起作用的執行內容在堆棧的最頂端。
每個執行內容都有一個與之關聯的範圍鏈,用於解析標識符。範圍鏈包含一個或多個變數對象,這些對象定義了執行內容範圍內的標識符。全域執行內容的範圍鏈中只有一個變數對象,它定義了JavaScript中所有可用的全域變數和函數。當函數被建立(不是執行)時,JavaScript引擎會把建立時執行內容的範圍鏈賦給函數的內部屬性[[Scope]]。然後,當函數被執行時,JavaScript引擎會建立一個使用中的物件(Activetion Object),並在初始化時給this、arguments、具名引數和該函數的所有局部變數賦值。使用中的物件會出現在執行內容範圍鏈的頂端,緊接其後的是函數[[scope]]屬性中的對象。
在執行代碼時,JavaScript引擎通過搜尋執行內容的範圍鏈來解析諸如變數和函數名這樣的標識符。解析標識符的過程從範圍的頂端開始,按照自上而下的順序進行。
驗證理論
function add(num1, num2) {
return num1 + num2;
}
當這段代碼執行開始時,add函數擁有一個僅包含全域變數對象的[[scope]]屬性。如:
在執行add函數時,JavaScript引擎會建立一個新的執行內容和一個包含this、arguments、num1、num2的使用中的物件,並把使用中的物件添加到範圍鏈中。在add()函數內部運行時,JavaScript引擎需要解析函數裡的num1和num2標識符。var total = add(5, 10);
解析過程是從範圍鏈中的第一個對象開始,這個對象就是包含該函數局部變數的使用中的物件。如果在該對象中沒有找到標識符,就會繼續在範圍鏈中下一個對象裡尋找標識符。一旦找到標識符,尋找就結束。
高效的資料存取
局部變數是JavaScript中讀寫最快的標識符。
一個好的經驗:任何非局部變數在函數中的使用超過一次時,都應該將其儲存為局部變數。
對於數組和對象,始終將那些需要頻繁存取的值儲存到局部變數中。
實際上每次存取HTMLCollection對象屬性,都會對DOM文檔進行動態查詢。
如果需要對HTMLCollection對象的成員反覆存取,高效的方式是將它們複製到數組裡。