1.保存函數執行狀態:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="father"> <p>保存函數執行狀態</p> <p>性能優化</p> <p>封裝函數</p> </div> </body> </html> <script> var list = document.getElementById('father').children; //保存函數執行狀態,保存現場(用於注冊事件比較多) //反面例子 function demo(nodes){ for(var i = 0; i < nodes.length; i++){ nodes[i].onclick = function(){ alert(i); } } } demo(list); //如上彈出的i永遠是3 // 使用閉包例子 function demo2(nodes){ function Closure(i){ return function(){ alert(i); } } for(var i = 0; i < nodes.length; i++){ nodes[i].onclick = Closure(i); } } demo2(list); </script>
2.封裝函數,實現信息隱藏,只暴露接口,外部無法訪問內部私有變量,內部變量可以訪問外部變量:
var func =(function(){ var arr = []; return { add:function(obj){ arr.push(obj); }, empty:function(){ arr = []; }, getCount:function(){ return arr.length; }, get:function(){ return arr; }, } })();
3.性能優化:
// 閉包使用舉例 -- 性能優化1 //減少函數定義時間和內存消耗 // 不使用閉包,每次執行sum就注冊一次add函數。 function sum(i, j) { var add = function(i, j){ return i+j; } return add(i, j) } var startTime = new Date(); for(var i = 0; i< 1000000; i++) { sum(1,1); } var endTime = new Date(); console.log(endTime - startTime); // 使用閉包,不用每次執行sum就注冊一次add函數。 var sum = (function() { var add = function(i, j){ return i+j; } return function(i,j) { add(i, j); } })(); var startTime = new Date(); for(var i = 0; i< 1000000; i++) { sum(1,1); } var endTime = new Date(); console.log(endTime - startTime);
/** 閉包使用舉例 -- 性能優化2 普通遞歸函數跟使用閉包記錄調用返回結果的遞歸函數調用次數對比 **/ // 普通遞歸函數 var factorial = (function(){ var count = 0; var fac = function(i){ count++; if (i==0) { console.log('調用次數:' + count); return 1; } return i*factorial(i-1); } return fac; })(); for(var i=0;i<=10;i++){ console.log(factorial(i)); } // 使用閉包記錄調用返回結果的遞歸函數 -- 記憶函數 var factorial = (function(){ var memo = [1]; var count = 0; var fac = function(i){ count++; var result = memo[i]; if(typeof result === 'number'){ console.log('調用次數:' + count); return result; } result = i*fac(i-1); memo[i] = result; return result; } return fac; })(); for(var i=0;i<=10;i++){ console.log(factorial(i)); }