为何数组索引0已定义仍出现Cannot read property '0' of undefined错误?
问题:JavaScript数组重组时出现"Cannot read property '0' of undefined"错误
需求说明
我正在写一段JavaScript代码,接收包含多个带category、itemName、onSale属性的对象数组,要把它重组为新对象:用原对象的category属性值作为新对象的属性,属性值是对应itemName的集合;如果原对象的onSale为true,就在itemName后加($)。测试时一直返回"Cannot read property '0' of undefined"错误,但数组索引0明明是已定义的。我是JS新手,代码可能不规范,求帮助。
已尝试的解决方法
- 拆分赋值语句,比如把
myObj = items[i]["category"][0];拆成:
myObj = items[i]["category"][0]; myObj.item[i] = ["category"][0];
- 修改for循环初始条件为
i = 1而非i = 0 - 输入不同数组比如
myArray = [1, 2, 3, 5],但还是出现类似错误,只是报错位置不同
我的代码
function organizeItems(items) { let myObj = {} for (let i = 0; i < items.length; i++) { if (items[i]["category"][0] in myObj === false) { if (items[i]["onSale"] === true) { myObj = items[i]["category"][0]; myObj.items[i]["category"][0] = []; myObj.items[i]["category"][0].push(items[i]["itemName"][0] + '($)'); } else { myObj = items[i]["category"][0]; myObj.items[i]["category"][0] = []; myObj.items[i]["category"][0].push(items[i]["itemName"][0]); } } else { if (items[i]["onSale"] === true) { myObj.items[i]["category"][0].push(items[i]["itemName"][0] + '($)'); } else { myObj.items[i]["category"][0].push(items[i]["itemName"][0]); } } } console.log(myObj); return myObj; } var iten = [1, 2, 3, 4, 5, 6]; var itemData = [ { category: 'fruit', itemName: 'apple', onSale: false }, { category: 'canned', itemName: 'beans', onSale: false }, { category: 'canned', itemName: 'corn', onSale: true }, { category: 'frozen', itemName: 'pizza', onSale: false }, { category: 'fruit', itemName: 'melon', onSale: true }, { category: 'canned', itemName: 'soup', onSale: false }, ]; organizeItems(itemData);
错误信息
/usr/src/app/test/unit_tests_spec.js:19 myObj.items[i]["category"][0] = []; ^ TypeError: Cannot read property '0' of undefined at organizeItems (/usr/src/app/test/unit_tests_spec.js:20:12) at Object.<anonymous> (/usr/src/app/test/unit_tests_spec.js:47:1) at Module._compile (module.js:653:30) at loader (/usr/src/app/node_modules/babel-register/lib/node.js:144:5) at Object.require.extensions.(anonymous function) [as .js] (/usr/src/app/node_modules/babel- register/lib/node.js:154:7) at Module.load (module.js:566:32) at tryModuleLoad (module.js:506:12) at Function.Module._load (module.js:498:3) at Module.require (module.js:597:17) at require (internal/module.js:11:18) at /usr/src/app/node_modules/mocha/lib/mocha.js:231:27 at Array.forEach (<anonymous>) at Mocha.loadFiles (/usr/src/app/node_modules/mocha/lib/mocha.js:228:14) at Mocha.run (/usr/src/app/node_modules/mocha/lib/mocha.js:514:10) at Object.<anonymous> (/usr/src/app/node_modules/mocha/bin/_mocha:480:18) at Module._compile (module.js:653:30) at Object.Module._extensions..js (module.js:664:10) at Module.load (module.js:566:32) at tryModuleLoad (module.js:506:12) at Function.Module._load (module.js:498:3) at Function.Module.runMain (module.js:694:10) at startup (bootstrap_node.js:204:16) at bootstrap_node.js:625:3 npm ERR! Test failed. See above for more details.
问题分析与修正代码
你的代码里有几个核心问题:
- 错误访问字符串索引:
items[i]["category"][0]是取category字符串的第一个字符,但你的category本身就是完整分类名(比如'fruit'),完全不需要加[0]。 - 错误覆盖myObj:
myObj = items[i]["category"][0];把原本的空对象改成了单个字符,后续访问myObj.items自然会报错——字符根本没有items属性。 - 错误的属性访问路径:
myObj.items[i]["category"][0]完全不符合你要构建的结构,正确的应该是myObj[category]直接访问分类对应的数组。
修正后的代码如下:
function organizeItems(items) { const organized = {}; for (const item of items) { // 直接解构获取当前项的属性 const { category, itemName, onSale } = item; // 处理显示名称:促销则追加($) const displayName = onSale ? `${itemName}($)` : itemName; // 如果分类不存在,先初始化空数组 if (!organized[category]) { organized[category] = []; } // 将处理后的名称加入对应分类的数组 organized[category].push(displayName); } console.log(organized); return organized; } const itemData = [ { category: 'fruit', itemName: 'apple', onSale: false }, { category: 'canned', itemName: 'beans', onSale: false }, { category: 'canned', itemName: 'corn', onSale: true }, { category: 'frozen', itemName: 'pizza', onSale: false }, { category: 'fruit', itemName: 'melon', onSale: true }, { category: 'canned', itemName: 'soup', onSale: false }, ]; organizeItems(itemData);
修正要点
- 使用对象解构直接获取item的属性,代码更简洁易读。
- 用
organized[category]直接访问分类对应的数组,避免多余的索引操作。 - 先判断分类是否存在,不存在则初始化空数组,防止后续push操作报错。
- 使用
for...of循环遍历数组,比传统for循环更直观,适合直接遍历数组元素。
运行这段代码后,会得到符合需求的结果:
{ fruit: ['apple', 'melon($)'], canned: ['beans', 'corn($)', 'soup'], frozen: ['pizza'] }
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

