作用域
全域作用域
局部作用域
作用域鏈
執行上下文
活動物件
閉包
閉包最佳化
JavaScript中出現了一個以前沒學過的概念——閉包。何為閉包?從表面理解即封閉的包,與作用域有關。所以,說閉包以前先說說作用域。
作用域(scope)
通常來說一段程式碼中使用的變數和函數並不總是可用的,限定其可用性的範圍即作用域,作用域的使用提高了程序邏輯的局部性,增強程序的可靠性,減少名字衝突。
全域作用域(Global Scope)
在程式碼中任何地方都能存取的物件擁有全域作用域,以下幾種情形擁有全域作用域:
1.最外層函數和在最外層函數外定義的變數擁有全域作用域,例如:
由此可見,函數的作用域鍊是創建函數的時候創建的。
執行上下文(Execute context )
函數add的作用域會在執行時用到,例如:
當我們載入頁面時,javascript中的newLoad函數已經運行完畢,由其中的循環可知,anchor已經賦值為4。但由先前的程式設計經驗來看,局部變數使用完畢就會銷毀,但是anchor卻沒有,顯然這裡 JavaScript 採用了另外的方式。
閉包在JavaScript 其實就是一個函數,在函數運行期被創建的,當上面的函數被執行的時候,會創建一個閉包,而這個閉包會引用newLoad 作用域中的anchor 。下面就來看看JavaScript 是如何來實現閉包的:當執行newLoad 函數的時候, JavaScript 引擎會建立newLoad函數執行上下文的作用域鏈,這個作用域鏈包含了newLoad執行時的活動對象,同時JavaScript 引擎也會建立一個閉包,而閉包的作用域鏈也會引用newload的活動對象,這樣當newload執行完的時候,雖然其執行上下文和活動對像都已經釋放了anchor,但是閉包還是引用著newload的活動對象,所以點選顯示的是「you clicked anchor4」。運行期間如圖:
閉包最佳化
既然閉包出現了我們不想看到的結果,我們需要優化它。最佳化後的javascript(其他不變):
結果分析:最佳化後的結果是因為,我們把宣告的變數和點選事件分開。用以上解釋的作用域鏈解釋:頁面加載,先執行listener函數,而listener函數需要anchor變量,在listener函數作用域鏈中沒有,會進入下一級作用域鏈,即查找newLoad中的anchor,因為在listener中已經確定了哪個anchor單擊對應哪個提示信息,所以只是在newload中查找對應的anchor而已,不會等循環完畢產生anchor4。
因為接觸javascript時間尚短,理解有誤的地方歡迎指正。