闭包的九种常用场景
闭包就是能够读取其他函数内部变量的函数
1. 返回值(最常见的一种)
var fn = function(){
var name = 'zjn'
return function(){
return name;
}
}
var fnc = fn();
fnc(); //zjn
2. 函数赋值
对(1)的变形将内部函数的值赋给函数外部的变量
var fn0;
var fn = function(){
var name = 'zjn'
return a = function(){
return name;
}
fn0 = a;
}
fn();
fn0(); //zjn
3. 函数参数
var fn0 = function(f){
console.log(f);
};
var fn = function(){
var name = 'zjn'
return a = function(){
return name;
}
fn0(a);
}
fn();//zjn
4. 立即执行函数(IIFE)
var fn0 = function(f){
console.log(f);
};
(function(){
var name = 'zjn'
return a = function(){
return name;
}
fn0(a);
})();//zjn
5. 循环赋值
function foo(){
var arr = [];
for (var i = 0; i< 10; i++){
// (function(n){
// arr[n] = function(){
// return n;
// };
// })(i);
arr[i] = (function(n){
return function(){
return n;
}})(i);
}
return arr;
}
var bar = foo();
console.log(bar[4]())
6. getter和setter函数
将要操作得变量保存在函数内部,防止暴露在外部
var getValue,setValue;
(function(){
var num = 0;
getValue = function(){
return num;
}
setValue = function(n){
num = (typeof n === 'number')? n:num;
}
})();
console.log(getValue()) //0
setValue(5);
console.log(getValue());//5
setValue('10');
console.log(getValue());//5
7. 迭代器
function setUp(arr){
var i = 0;
return function(){
return arr[i++]
}
}
var arr = ['asd','fgh','jkl','zxc']
var next = setUp(arr);
console.log(next())//asd
console.log(next())//fgh
console.log(next())//jkl
console.log(next())//zxc
console.log(next())//undefined
8. 区分首次
var firstLoad = (function(){
var list = [];
return function(id){
if(list.indexOf(id)==-1){
list.push(id);
return true;
}else{
return false;
};
}
})();
console.log(firstLoad(444))//true
console.log(firstLoad(444))//false
9. 模拟缓存机制
避免相同数据的重复操作
- 未加入缓存机制
function mult() {
var sum = 0;
for(var i = 0; i< arguments.length; i++){
sum +=arguments[i];
}
return sum;
}
console.log(mult(1,3,2,16,5,4,8,4))//43
- 加入缓存机制 :将已执行过的参数以key的形式放置在引用参数(数组/对象)中,每次执行时,若已存在,则直接返回缓存中的数据,若不存在,再执行操作
var mult = (function(){
var cache = {};
var calc = function(){
var sum = 0;
for(var i = 0; i< arguments.length; i++){
sum += arguments[i];
}
return sum;
}
return function(){
var args = Array.prototype.join.call(arguments,'+');
if(args in cache){
return cache[args] + ' from cache';
}else{
return cache[args] = calc.apply(null,arguments);
}
}
})();
console.log(mult(1,2,1,5,6,4,8,4,9))//40
console.log(mult(1,2,1,5,6,4,8,4,9))//40 from cache