如何将购物车总价存入localStorage?代码出现NaN报错该如何解决
代码存在的问题
- 错误使用
for...in遍历localStorage:for...in会遍历localStorage原型链上的内置属性(比如getItem、setItem、length等),遍历到这些属性时localStorage.getItem(key)返回null,JSON.parse后还是null,后续访问product.price得到undefined,运算后就会出现NaN报错。 - 累加前未重置变量和清空DOM:全局变量
Total、products数组以及购物车表格内容cartTablebody.innerHTML在每次执行displayProduct时都没有先清空重置,如果多次调用该函数(比如新增商品后重新渲染),就会把旧的总价和商品重复累加,刷新页面时也会因为重复渲染导致总价偏高。 - 商品数量统计逻辑错误:直接用
localStorage.length作为购物车商品数量,如果你本地存储还存了其他业务数据,会导致数量统计错误,且赋值操作放在循环里重复执行无意义。 - 缺少对商品字段的校验:没有判断解析后的product对象是否存在
price、title字段,即使是正常的商品数据,如果字段缺失也会触发NaN。
修复后的代码
let totalityPrice = document.querySelector('.subtotal'); let products = []; let Total = 0; const cartTablebody = document.querySelector('tbody'); // 补全表格DOM获取 function displayProduct() { // 每次渲染前先重置所有数据和DOM,避免重复累加 Total = 0; products = []; cartTablebody.innerHTML = ''; const validProducts = []; // 用Object.keys()只取localStorage的自定义键,过滤内置属性 const storageKeys = Object.keys(localStorage); for (let key of storageKeys) { try { const product = JSON.parse(localStorage.getItem(key)); // 校验是合法的商品数据再处理 if (product && typeof product.price === 'number' && product.title) { validProducts.push(product); products.push(key); cartTablebody.innerHTML += ` <tr> <td>${product.title}</td> <td>${product.price / 100}</td> </tr> `; Total += product.price / 100; } } catch (e) { // 过滤掉非JSON格式的无效存储项 continue; } } // 最后统一更新购物车数量,用实际有效商品数统计 document.querySelector('.cart span').textContent = validProducts.length; } displayProduct(); function calculatePrice() { totalityPrice.innerText = Total.toFixed(2); // 保留两位小数优化显示 localStorage.setItem('cartTotal', Total); console.log(Total); } calculatePrice();
额外注意点
- 新增商品时不要直接拼接DOM,调用
displayProduct()重新渲染全量购物车即可,避免数据不同步 - 建议给购物车商品的存储键加统一前缀(比如
cart_xxx),方便和其他存储数据区分,遍历的时候可以过滤掉非购物车的键
内容的提问来源于stack exchange,提问作者ZeyennaStudy
相关产品推荐
相关产品推荐

