閉包
首先說說閉包,閉包的官方定義:能夠訪問其他函數作用域的變量的函數,並且該函數可以起到讓其他作用域中變量保存的作用。最常見的用法就是在父函數中
套用子函數來用閉包。爲什麼要用閉包呢,任何一個技術出現的前提必然是需求。要知道js中是沒有靜態變量的,函數變量在函數執行後立即被垃圾回收,我們當然可以用全局變量,但是過多的全局變量會導致代碼難以維護,所以我們就要採用閉包。代碼示例如下,在函數A執行後,匿名函數被外界引用,那麼函數A中的變量i就沒有隨着函數A的執行完畢被垃圾回收,此變量一直保持在內存中。
function A(){
var i=1;
return function(){
alert(++i);
}
}
var b=A();
b();//2
b();//3
閉包的第二種用法,就是循環綁定事件了,循環綁定如下事件後,單擊每個div,觸發的都是alert(9),因爲代碼是在單擊時執行的,所以會去查找循環後的i變量i=10;
for (var i=0;i<10;i++){
div.bind('click',function(){
alert(i);
})
}
修改如下,講變量i複製一份給index,則內部的匿名函數就形成了閉包,他可以讓傳遞進來的index實參保存,不被垃圾回收。
for(var i=0;i<10;i++){
div.bind('click',(function(index){
return function(){
alert(index)
}
})(i))
}
作用域與作用域鏈
在此需要說一下執行環境的概念,作用域是語言中通用的概念,而作用域鏈與執行環境是js中特有的。執行一個函數時,都會進入一個執行環境,這個執行環境中存儲了當前
作用域的方法和屬性。當前執行環境在執行棧的最底層,window的執行環境在最上層。訪問一個變量,如果在當前執行環境中不存在,則需要沿着作用域鏈向上層執行環境中
去查找。當前代碼執行完畢,當前執行環境銷燬,將執行權返還給上層的執行環境。