尝试向数组push元素报错:TypeError: push() is not a function
解决Uncaught TypeError: data.allItems[type].push is not a function
这个错误我太熟悉了——push is not a function本质上就是告诉你,你试图在非数组的东西上调用数组的push方法。咱们一步步拆解问题:
错误根源分析
从你的代码看,data.allItems初始时exp和inc都是数组:
var data = { allItems: { exp: [], inc: [] }, totals: { exp: 0, inc: 0 }, budget: 0, percentage: -1 };
但报错时data.allItems[type]肯定不是数组,大概率是以下两种情况:
1. 传入的type参数不合法
你调用addItem时,传入的type不是'exp'或'inc'(比如拼写错误成'expense'、'income',或者传了其他字符串)。这时候data.allItems[type]会是undefined,而undefined没有push方法,自然报错。
2. 其他代码意外修改了data.allItems的结构
在调用addItem之前,某个地方的代码把data.allItems.exp或data.allItems.inc改成了非数组类型(比如字符串、对象、数字)。比如不小心写了:
data.allItems.exp = '午餐开销'; // 覆盖了原数组
之后再调用push就会失败。
解决方案
方案1:添加参数校验,杜绝非法type
在addItem函数开头先校验type的合法性,提前抛出明确错误,避免模糊的push报错:
addItem: function(type, des, val) { // 先校验type是否为合法值 if (!['exp', 'inc'].includes(type)) { throw new Error(`Invalid type: ${type}. Must be "exp" or "inc"`); } var newItem, ID; // 创建新ID if (data.allItems[type].length > 0) { ID = data.allItems[type][data.allItems[type].length - 1].id + 1; } else { ID = 0; } // 根据'inc'或'exp'类型创建新元素 if (type === 'exp') { newItem = new Expense(ID, des, val); } else if (type === 'inc') { newItem = new Income(ID, des, val); } // 将元素存入数据结构 data.allItems[type].push(newItem); // 返回新元素 return newItem; },
方案2:防御式编程,确保目标是数组
如果担心其他代码意外修改了数组,可以在push前检查并重置:
// 将元素存入数据结构 if (!Array.isArray(data.allItems[type])) { // 重置为数组,或者抛出错误提醒 data.allItems[type] = []; // 或者用抛出错误替代: // throw new Error(`data.allItems.${type} has been overwritten to a non-array value`); } data.allItems[type].push(newItem);
方案3:排查所有修改data.allItems的代码
全局搜索你的代码,找到所有修改data.allItems.exp或data.allItems.inc的地方,确保没有直接覆盖数组的操作(比如不要用=赋值,而是始终用数组方法操作)。
内容的提问来源于stack exchange,提问作者n.kilani




