JS遍历WooCommerce商品数组时报undefined的name属性读取错误
问题根因
这个报错和数据量提升没有直接关联,是代码本身的逻辑漏洞导致的,10条测试数据能正常运行纯粹是没触发边界条件:
- 循环边界硬编码为1550,但实际商品总数只有1470,当索引超过数组真实长度时,
secondary[i]或main[counter]会返回undefined,读取.name属性必然抛出类型错误。 - 遍历过程中执行secondary数组元素删除操作时,数组长度会动态缩短,但代码用的是正序递增索引
i++,删除元素后后续项会自动前移,很容易出现索引跳变、越界、漏遍历的问题。 - 用商品名
name做匹配依据不可靠,WooCommerce允许商品重名,会出现误匹配、误删除的问题。 - 双层循环的匹配逻辑时间复杂度为O(n*m),1470条数据最坏情况要执行200多万次比较,数据量继续增大会直接卡住浏览器主线程。
修复后代码
async function deleter() { const main = main_products; // 对secondary数组做浅拷贝,避免遍历过程中原数组改动干扰索引 let secondary = [...secondary_products]; const statusDom = document.getElementById("delete"); const needDeleteIds = []; // 提前将主商品库的唯一id存入Set,单次匹配时间复杂度从O(n)降到O(1) const mainProductIdSet = new Set(main.map(product => product.id)); // 倒序遍历数组,删除元素不会影响未遍历项的索引 for (let i = secondary.length - 1; i >= 0; i--) { const currentProduct = secondary[i]; // 用唯一id做匹配,避免重名导致的误判 if (mainProductIdSet.has(currentProduct.id)) { console.log("找到匹配商品 -> " + currentProduct.name); continue; } console.log(`主库未找到商品 -> ${currentProduct.name},启动删除流程`); console.log("待删除商品id:", currentProduct.id); needDeleteIds.push(currentProduct.id); } // 批量执行删除操作,减少重复请求和DOM操作 if (needDeleteIds.length > 0) { for (const id of needDeleteIds) { // 确保deletedata方法接收商品id作为参数,精准删除对应商品 await deletedata(id); } statusDom.innerHTML = "处理完成 ✔️"; } else { statusDom.innerHTML = "无待删除商品 ✔️"; } // 最终更新原secondary数组,移除已删除商品 secondary_products = secondary.filter(product => !needDeleteIds.includes(product.id)); }
注意事项
- 所有数组遍历不要硬编码长度,统一通过
数组.length获取实时长度,从根源避免索引越界问题。 - 遍历过程中需要删除数组元素时,优先用倒序遍历,或者先遍历收集完全部待处理项再统一操作,不要边正序遍历边删元素。
- WooCommerce商品匹配必须用
id字段作为唯一依据,不要用name、sku这类可重复、可修改的字段做匹配键,避免误删商品。 - 千条以上数据做集合匹配时,用Set/Map结构存储匹配键,性能比双层循环高两个数量级,避免页面卡顿。
- 涉及DOM操作、接口请求的逻辑,尽量批量执行,不要每处理一条就触发一次,减少不必要的性能开销。
内容的提问来源于stack exchange,提问作者Tehgreekplayer
相关产品推荐
相关产品推荐

