请教calculateCartTotal函数的for/in循环取值逻辑及扩展疑问
解答
1. 原代码“精准”获取的本质:依赖属性插入顺序
ES2015(ES6)及以后的规范中,对象的自有可枚举属性会按照插入顺序排列(整数类型的键会被优先排序,这里的quantity、priceInCents都是字符串键,不受此规则影响)。
原代码中每个商品对象的属性是先定义quantity,再定义priceInCents,所以Object.values(cart[item])返回的数组顺序是[quantity值, priceInCents值],通过索引[0]和[1]就能取到对应值。但这不是“精准设计”的结果,只是刚好依赖了属性的定义顺序。
2. 新增weight后的取值逻辑:取决于属性插入位置
原代码的逻辑并不安全,新增weight后是否会取到它,完全看你把weight插在哪个位置:
- 如果把
weight加在priceInCents之后:{ quantity: 1, priceInCents: 1000, weight:24 }Object.values()返回[1, 1000, 24],此时[1]还是priceInCents的值,看起来没问题,但这只是巧合。 - 如果把
weight插在quantity和priceInCents之间:{ quantity: 1, weight:24, priceInCents: 1000 }Object.values()返回[1,24,1000],此时[1]取到的是weight的值,计算总价时就会出错。
3. 正确的写法:直接通过属性名访问
依赖属性顺序的写法非常脆弱,只要属性定义顺序变了就会出问题。正确的做法是直接通过属性名获取值,不管顺序如何都能精准拿到:
function calculateCartTotal(cart) { let total = 0; for (const item in cart){ const { quantity, priceInCents } = cart[item]; total += priceInCents * quantity; } return total; } function printCartInventory(cart) { let inventory = ""; for (const item in cart){ inventory += `${cart[item].quantity}x${item}\n`; } return inventory; }
内容的提问来源于stack exchange,提问作者Mahjur
相关产品推荐
相关产品推荐

