每個函數存在一個[[Scope]]
內部屬性,包含了一個函數被建立得做用域中對象得集合,這個集合爲函數得做用域鏈。例以下面的全局函數:閉包
fucntion add(num1, num2){ var sum = num1 + num2; return sum; }
當函數add
被建立時,它的做用域鏈中便插入了一個對象變量,裏面包含全部在全局範圍內定義的變量。
函數add
的做用域會在函數執行時用到,函數每次執行都會建立一個執行環境
的內部對象,每一個執行環境都有本身的做用域鏈。函數運行時,一個被稱爲活動對象
的新對象就爲執行環境建立好了,裏面包含了函數的全部局部變量,命名參數,參數集合以及this。假設執行var total = add(5,10)
,其對應的做用域鏈以下:
函數執行過程當中,變量的查找時從做用域頭部開始查找,若是找到就是使用改變量的值。若是找不到就繼續從做用域下一個對象查找,直到找到改變量。如過匹配不到,則爲undefined。當頻繁使用全局變量時,能夠先使用一個局部變量保存起來,以後直接訪問局部變量能夠減小查找次數提升效率。例如:函數
function initUI(){ var doc = document, bd = doc.body, links = doc.getElementsByTagName("a"); .... }
當函數執行完成,活動對象也會隨之銷燬。但閉包時,活動對象並不會銷燬。這也是爲何閉包占用內存大的緣由。性能
資料:《高性能JavaScript》第2章節this