作者提到循环的陷阱
for( var i = 0;i<files.length;i++){
fs.readFile(files[i],'utf-8',function (err,contents) {
console.log(files[i] + ':' + contents);
})
}
结果是
undefined:AAA
undefined:BBB
undefined:CCC
这个不难理解,作者建议改成这样,但是没有解释
files.forEach(function (filename) {
fs.readFile(filename,'utf-8',function (err,contents) {
console.log(filename+':'+contents);
})
})
我不懂,为什么把for改成forEach就解决问题了,for与forEach本质区别在哪里
这是经典的js闭包问题,题主可自行查阅
forEach算是FP的半成品
这个其实跟 for 和 forEach 没什么关系,是写 javascript 闭包的一个经常犯的错误,可参考: Creating closures in loops: A common mistake
闭包会把当前的环境保存下来,原来的代码里面那个 for 创建了若干个闭包,但是每个闭包共享上下文环境 i。因为 for (很大可能)会先跑完,所以运行回调函数的时候 i 已经变成了 files.length,这时候 files[i] 因为超过数组边界,所以就 undefined 了。
写 for 其实也没问题,用 function factory 就可以。
function gencb(filename) {
return function (err, contents) {
if (err) //...
console.log(filename + ':' + contents);
};
};
for( var i = 0;i<files.length;i++){
fs.readFile(files[i],'utf-8', gencb(files[i]))
}
这个代码因为每次闭包都不一样(包括filename),所以就正常了
for循环的时候i每次都是files.length所以找不到。 也可以这样改: for( var i = 0;i<files.length;i++){ (function(i){ fs.readFile(files[i],‘utf-8’,function (err,contents) { console.log(files[i] + ‘:’ + contents); }); })(i); }
感谢,对闭包的理解又深了一步
也就是说forEach
不存在上下文环境这个问题?
使用js必然会遇见的闭包问题
for( var i = 0;i<files.length;i++){
fs.readFile(files[i],'utf-8',function (err,contents) {
//这一部分是异步执行的,其实差不多等到for循环完成才会执行,所以这时候的i==files.length ,懂了吗?
console.log(files[i] + ':' + contents);
})
}
顶一个,很好的知识点。
i 每次循环 复制一份就好啦
闭包啊
包装一层函数(闭包)会保持当前参数,so~