JavaScript查找嵌套配件对象并按汇率单位规则计算总金额咨询
现有参考代码的问题
首先你参考的实现有几个需要调整的点:
unitMultiplier和length都依赖外部上下文变量,没有作为参数传入函数,很容易出现变量污染、取值异常的问题toFixed()返回的是字符串类型,直接参与乘法运算会触发隐式类型转换,有概率出现精度错误- 多层三元判断币种的写法可读性很差,后续新增币种维护成本很高
- 没有做配件匹配容错,一旦产品关联的配件在基础配件数组里找不到,会直接报错
优化实现方案
1. 调整汇率配置为对象格式
把汇率统一存在对象里,后续加币种直接加键值对就行,不用额外加判断逻辑:
// 统一汇率配置,所有币种统一换算为USD计价 const EXCHANGE_RATE = { eur: 1.18, gbp: 1.38, usd: 1 // 本位币汇率固定为1 }
2. 封装单价计算逻辑
所有依赖的参数都显式传入,不依赖外部上下文,稳定性更高:
/** * 计算单个配件换算后单价(USD计价) * @param {Object} accessory 基础配件配置对象 * @param {Number} length 产品长度(单位:mm) * @returns {Number} 换算后单价 */ function calcAccessoryUnitPrice(accessory, length) { // 汇率换算,取不到对应币种汇率默认按1计算 const rate = EXCHANGE_RATE[accessory.currency] ?? 1 let price = accessory.price * rate // 按单位计算长度乘数 const unitMultiplier = accessory.unit === 'm' ? length / 1000 : 1 return price * unitMultiplier }
3. 封装总金额计算逻辑
用reduce直接做累加,不用先map再reduce,性能更好,同时加了匹配容错:
/** * 计算单个产品规格下的配件总金额 * @param {Object} property 产品属性对象 * @param {Array} baseAccessories 全局基础配件配置数组 * @returns {String} 总金额,保留两位小数 */ function calcPropertyAccessoriesTotal(property, baseAccessories) { const length = Number(property.length) || 0 return property.accessories.reduce((total, prodAcc) => { // 匹配对应基础配件配置 const baseAcc = baseAccessories.find(item => item.name === prodAcc.name) // 匹配不到默认累加0,可根据需求调整为抛出错误 if (!baseAcc) return total const unitPrice = calcAccessoryUnitPrice(baseAcc, length) return total + unitPrice * prodAcc.qty }, 0).toFixed(2) }
4. PUG模板调用示例
直接在循环产品属性的时候调用函数即可:
each product in products each prop in product.properties - const accessoriesTotal = calcPropertyAccessoriesTotal(prop, accessories) | 当前规格配件总金额:#{accessoriesTotal} USD
测试验证
用你给出的示例数据计算结果为:
- Accessory-1:1 EUR * 1.18汇率 = 1.18 USD,单位为m,长度2000mm换算为2m,单价变为1.18 * 2 = 2.36 USD,乘以数量1后为2.36 USD
- Accessory-2:2 USD 无需汇率换算,单位为pcs无需乘长度,乘以数量1后为2 USD
- 总金额为 2.36 + 2 = 4.36 USD,和计算逻辑预期一致
内容的提问来源于stack exchange,提问作者Kene
相关产品推荐
相关产品推荐

