javascript闭包的确是一个特点也是我们初学者难理解的地方,感觉功能像是C里面的static,但肯定不是这里先挖个坑。
年前写了点代码,记录一下javascript闭包的简单实践。
1. 循环内回调
例如我要写一个查询多个文件是否存在并删除,在Node.js中
var fs = require('fs');
var path = require('path');
fs.readdir(path.resolve('test'),function(err,files){
console.log(files);
for(var file in files){
var filePath = path.resolve('test',files[file]);
fs.exists(filePath,function(exists){
console.log('filePath',filePath,exists);
if(exists)
fs.unlink(filePath,function(err){
if(err) console.log(err);
})
})
}
})
会发现只能删除一个,仔细看一下log中的变量发现循环“不管用了”,当文件查找是否存在时全是最后一个文件。这是因为我们用的是filesystem的异步方法,当他执行时我们的for中的file变量早就是最后那一个了,自然会出问题。
我们将filepath变量进行闭包处理,即使循环结束,fs函数也会顺着作用域链找到外部变量。
var fs = require('fs');
var path = require('path');
fs.readdir(path.resolve('test'),function(err,files){
console.log(files);
for(var file in files){
var filePath = path.resolve('test',files[file]);
(function(filepath){
fs.exists(filepath,function(exists){
console.log('filepath',filepath,exists);
if(exists)
fs.unlink(filepath,function(err){
if(err) console.log(err);
})
})
})(filePath)
}
})
forEach可以简单解决
2. 复杂计算的缓存
之前有过一个需要大量计算的场景(其实不算很大10ms左右的计算量),还好每天只需要计算一次。
这里我们将arr作为cache储存起来,把arr,today进行闭包处理。当下一次需要计算时判断,能够节省计算量。
arr.push(1)模拟大量计算
var timeFilterArr = (function(){
var arr = [];
var today = new Date().toDateString();
return function(){//闭包处理缓存代理
var time = new Date().toDateString();
if(arr.length !== 0 && today === time){
console.log('have calculated');
return arr;
}
console.log('calculating');
arr.push(1);
today = new Date().toDateString();
return arr;
}
})();
timeFilterArr();
timeFilterArr();
timeFilterArr();`
以后再写到闭包,或再有新的理解会继续填坑?