Node.js中fs.readFileSync读取JSON文件返回重复结果问题排查
循环处理JSON数据时用户残留问题的原因分析
问题背景
我正在处理两个JSON文件:sorted/apr-total2.json和sorted/may-total2.json,仅apr的文件包含用户John的数据,may的文件中无该用户。执行代码时,循环处理两个月的数据,两次都检测到John存在,不符合预期;但在循环末尾删除对象属性后,结果恢复正常。
相关代码
let months = ["apr", "may"]; let dataToSort = {}; function getDataFromJSONFile(month) { let jsonData = fs.readFileSync(`sorted/${month}-total2.json`); let convertedData = JSON.parse(jsonData); return convertedData; } function arrayToObject(data) { data.forEach((user) => { dataToSort[user[0].toString()] = user[1]; }); return dataToSort; } for (let i in months) { let currentMonth = months[i]; console.log("Current month is " + currentMonth); let getDataForMonth = getDataFromJSONFile(currentMonth); let convertedMonth = arrayToObject(getDataForMonth); if (convertedMonth.hasOwnProperty("John") == true) { console.log(true); } }
原输出
Current month is apr true Current month is may true
添加删除属性后的输出
Current month is apr true Current month is may
原因分析
问题核心在于全局变量dataToSort被重复复用:
- 第一次循环处理apr数据时,
arrayToObject函数将John的属性写入了全局的dataToSort对象,此时该对象已存有John的键值对。 - 第二次循环处理may数据时,
arrayToObject只是把may文件中的用户数据追加到dataToSort中,并不会清除之前已有的John属性。所以即便may文件里没有John,convertedMonth(也就是全局的dataToSort)里仍保留着第一次循环留下的John数据,导致检测结果始终为true。
添加删除属性的操作后,每次循环结束都会清除John的属性,第二次循环时dataToSort中没有残留数据,结果就符合预期了。
最优解决方法
无需手动删除属性,直接把dataToSort的声明移到arrayToObject函数内部,让每次调用函数时都创建一个全新的空对象,彻底避免全局对象的复用:
function arrayToObject(data) { let dataToSort = {}; // 移到函数内部,每次调用都生成新对象 data.forEach((user) => { dataToSort[user[0].toString()] = user[1]; }); return dataToSort; }
内容的提问来源于stack exchange,提问作者Mentalhead
相关产品推荐
相关产品推荐

