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));
}