如何遵循DRY原则优雅消除代码中parsedData重复引用?
优雅去除
parsedData.前缀的几种DRY方案 这问题我太熟了!要去掉重复的parsedData.前缀,同时遵循DRY原则,有几种非常优雅的方案,我给你一一拆解:
方法一:嵌套对象解构+重命名(最直观推荐)
直接在函数开头对parsedData进行解构,把需要的顶层属性和嵌套属性一次性拆出来,甚至可以直接在解构时重命名成finalData需要的属性名,这样后续赋值就完全不用写前缀了:
function foo(parsedData) { // 一次性解构并重命名所有需要的属性 const { KPP, OGRN, name: { short: principalShortName, full: principalFullName }, address: { legal: principalLegalAddress, real: principalRealAddress }, OKATO, history: { registration, taxRegistration }, OKOPF, OKVED, head: { fullName: headFullName, title: headTitle } // 原代码这里headTitle写错成fullName了,我帮你修正了 } = parsedData; const finalData = { KPP, OGRN, principalShortName, principalFullName, principalLegalAddress, principalRealAddress, OKATO, principalRegistrationDate: moment(registration), principalTaxRegistrationDate: moment(taxRegistration), OKOPF, OKVED, headFullName, headTitle }; // 后续可以返回或处理finalData }
这种方式的优点是代码可读性极强,每一步的映射关系一目了然,完全符合DRY原则,也不需要额外的工具函数。
方法二:展开运算符+部分手动映射
如果你的finalData里大部分顶层属性和parsedData的顶层属性同名(比如KPP、OGRN这些),可以先用展开运算符把这些同名属性直接拿过来,再单独处理嵌套的属性:
function foo(parsedData) { // 先把嵌套的对象和其他不需要直接展开的属性拆出来 const { name, address, history, head, ...rest } = parsedData; const finalData = { ...rest, // 直接展开所有同名的顶层属性:KPP、OGRN、OKATO、OKOPF、OKVED principalShortName: name.short, principalFullName: name.full, principalLegalAddress: address.legal, principalRealAddress: address.real, principalRegistrationDate: moment(history.registration), principalTaxRegistrationDate: moment(history.taxRegistration), headFullName: head.fullName, headTitle: head.title }; }
这种方法能进一步减少代码量,适合顶层属性较多且同名的场景。
方法三:映射规则+reduce(适合复用场景)
如果这种属性映射逻辑需要在多个地方复用,或者需要动态调整映射关系,可以定义一个映射规则数组,然后用reduce来生成finalData:
function foo(parsedData) { // 定义映射规则:[finalData属性名, parsedData路径, 可选的转换函数] const propertyMappings = [ ['KPP', 'KPP'], ['OGRN', 'OGRN'], ['principalShortName', 'name.short'], ['principalFullName', 'name.full'], ['principalLegalAddress', 'address.legal'], ['principalRealAddress', 'address.real'], ['OKATO', 'OKATO'], ['principalRegistrationDate', 'history.registration', val => moment(val)], ['principalTaxRegistrationDate', 'history.taxRegistration', val => moment(val)], ['OKOPF', 'OKOPF'], ['OKVED', 'OKVED'], ['headFullName', 'head.fullName'], ['headTitle', 'head.title'] ]; const finalData = propertyMappings.reduce((result, [key, path, transform]) => { // 解析嵌套路径获取对应值 const value = path.split('.').reduce((obj, prop) => obj[prop], parsedData); // 应用转换函数(如果有的话) result[key] = transform ? transform(value) : value; return result; }, {}); }
这种方式的优势在于扩展性极强,后续要修改或新增属性映射,只需要调整propertyMappings数组即可,不需要改动赋值逻辑,非常适合复杂或需要复用的场景。
小提醒
原代码里headTitle赋值的是parsedData.head.fullName,看起来应该是笔误,我在所有方案里都改成了head.title,如果实际需求就是fullName,你再改回去就行~
内容的提问来源于stack exchange,提问作者avalanche1
相关产品推荐
相关产品推荐

