Node.js脚本中menu.forEach函数TypeError报错的解决方法
你编写的Node.js脚本用于将JSON文件数据插入Firestore时,触发了TypeError: menu.forEach is not a function错误,以下是问题详情及修复方案:
原代码
var admin = require("firebase-admin"); var serviceAccount = require("./service_key.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://xxxxxxxxx.firebaseio.com" }); const firestore = admin.firestore(); const path = require("path"); const fs = require("fs"); const directoryPath = path.join(__dirname, "files"); fs.readdir(directoryPath, function(err, files) { if (err) { return console.log("Unable to scan directory: " + err); } files.forEach(function(file) { var lastDotIndex = file.lastIndexOf("."); var menu = require("./files/" + file); menu.forEach(function(obj) { firestore .collection(file.substring(0, lastDotIndex)) .doc(obj.itemID) .set(obj) .then(function(docRef) { console.log("Document written"); }) .catch(function(error) { console.error("Error adding document: ", error); }); }); }); });
报错信息
/Users/nana/Documents/SCRIPT/uploader.js:25 menu.forEach(function(obj) { ^ TypeError: menu.forEach is not a function at /Users/nana/Documents/SCRIPT/uploader.js:25:10 at Array.forEach (<anonymous>) at /Users/nana/Documents/SCRIPT/uploader.js:20:9 at FSReqCallback.oncomplete (node:fs:188:23)
错误原因
forEach是数组专属方法,报错说明你通过require导入的menu不是数组类型,大概率是以下两种情况:
- JSON文件内容是对象格式(用
{}包裹)而非数组格式(用[]包裹) - JSON文件的结构不符合预期,导致导入后不是可遍历的数组
修复方案
方案1:修正JSON文件格式(如果预期是数组)
检查files目录下的JSON文件,确保内容是数组结构,示例:
[ {"itemID": "menu_001", "name": "招牌汉堡", "price": 29}, {"itemID": "menu_002", "name": "可乐", "price": 8} ]
方案2:适配对象类型的JSON文件(如果JSON确实是对象)
如果你的JSON文件是键值对结构(比如{"menu_001": {...}, "menu_002": {...}}),需要改用遍历对象值的方式,替换原代码中的menu.forEach部分:
// 替换原有的menu.forEach逻辑 Object.values(menu).forEach(function(obj) { firestore .collection(file.substring(0, lastDotIndex)) .doc(obj.itemID || Object.keys(menu).find(key => menu[key] === obj)) // 若obj无itemID,可改用对应的键 .set(obj) .then(function(docRef) { console.log("Document written"); }) .catch(function(error) { console.error("Error adding document: ", error); }); });
方案3:增加类型校验(提升代码容错性)
在遍历前先判断menu的类型,避免非预期格式触发报错:
var menu = require("./files/" + file); // 先判断类型再处理 if (Array.isArray(menu)) { menu.forEach(function(obj) { // 原数组遍历逻辑 firestore .collection(file.substring(0, lastDotIndex)) .doc(obj.itemID) .set(obj) .then(function(docRef) { console.log("Document written"); }) .catch(function(error) { console.error("Error adding document: ", error); }); }); } else if (typeof menu === 'object' && menu !== null) { // 处理对象类型的JSON Object.values(menu).forEach(function(obj) { firestore .collection(file.substring(0, lastDotIndex)) .doc(obj.itemID || Object.keys(menu).find(key => menu[key] === obj)) .set(obj) .then(function(docRef) { console.log("Document written"); }) .catch(function(error) { console.error("Error adding document: ", error); }); }); } else { console.log(`跳过文件${file}:格式不支持(既不是数组也不是对象)`); }
内容的提问来源于stack exchange,提问作者Ruben's A.
相关产品推荐
相关产品推荐

