啥是閉包?
閉包是能讀取其他函數內部變量的函數,js中能讀取一個函數內部變量的只有該函數的后代函數,在函數的外部是訪問不了函數的變量的.
需要操作某個函數的內部變量時,不能把所有的操作都放在函數內部,這樣就需要內部函數作為一個橋梁,將函數的信息輸送出來
注意一點,在函數內部聲明變量時必須要使用var,否則系統會認為你聲明的是一個全局變量
聲明變量時,如果不寫var,系統會認為聲明的是window.a,即window對象的屬性
閉包有啥用?
1.可以防止全局的命名空間被污染
--如果要寫一個累加器,不使用閉包的話,就必須定義一個全局的變量來接收
var count = 0; function add(){ count++; console.log(count); }
//每次調用add函數count就會加1 add(); add(); add();
//這個函數如果count變量放在函數內部,每次調用函數時count都會被重置為0,不能達到累加的作用
//如果使用閉包就不會出現這一問題
2.便於模塊化開發
使用閉包開發的項目各個功能都被封裝到了各自的函數中,之間互不影響
3.安全性
將變量都變為私有的,只有通過內部函數才能訪問函數的變量,能夠提高成程序的安全性
閉包咋寫啊?
上面的例子如果寫成閉包的形式就是這樣:
function add(){ var count = 0; function inner(){ count++; console.log(count); } return inner;
//將內部函數作為返回值返回 } var outer = add();//定義一個變量接收add函數的返回值 outer(); outer(); outer();
//在函數外add函數外直接訪問count變量是不可能的,但是通過閉包就可以實現
閉包經常與for循環和匿名自調用函數結合:
<!DOCTYPE html> <html> <head> <title>模擬一個非誠勿擾的場景</title> <script type="text/javascript"> window.onload = function(){ var btn = document.querySelectorAll('.choiceArea>button'); function demo(){ for(var i=0;i<btn.length;i++){ //每次循環都將i作為一個參數賦值給j (function(j){ btn[j].onclick =function(){ alert("你的的選擇是"+(j+1)+"號女嘉賓"); } }(i)); }; } demo(); } </script> </head> <body> 請選擇你的心動女生:<br /> <form class="choiceArea"> <button>1號女嘉賓</button> <button>2號女嘉賓</button> <button>3號女嘉賓</button> <button>4號女嘉賓</button> <button>5號女嘉賓</button> </form> </body> </html>
閉包的缺點
正常函數執行結束之后會立即銷毀,而閉包因為存在引用會一直存在在內存中,如果閉包過多就會在內存中占用大量資源,影響程序的性能.