如何编写JS通用函数实现多版本配置嵌套属性取值缺省回退
1. 直接写三元判断确实会抛出错误
你说的情况是对的,如果变体版本下不存在landingPage属性,funnelData[version]["landingPage"]会返回undefined,此时再读取primaryHeadline就会抛出Cannot read properties of undefined (reading 'primaryHeadline') 报错。
2. 现有配置方案合理性
你当前的配置方案是合理的:仅在变体中存储增量修改的内容,原始版本作为全量兜底,既减少了冗余配置,也便于后续维护多个变体版本,不需要每次新增变体都复制全量配置。
3. 两种实现方案
方案1:原生语法快速实现(不需要额外封装函数)
用ES2020新增的可选链运算符?. + 空值合并运算符?? 即可实现安全取值+自动兜底,写法简单:
// 示例:取primaryHeadline const primaryHeadline = websiteData[version]?.landingPage?.primaryHeadline ?? websiteData.original.landingPage.primaryHeadline;
可选链会在任意一层属性不存在时直接返回undefined,不会抛出错误;空值合并运算符会在前面的值为undefined/null时,自动返回后面的兜底值。
方案2:通用多层取值函数封装
如果要做通用工具函数,支持传入任意深度的属性路径,可以参考如下实现:
const getElement = (version, propertyPath) => { // 先从指定版本逐层取值 let target = websiteData[version]; for (const key of propertyPath) { target = target?.[key]; if (target === undefined) break; } // 指定版本能取到值直接返回,否则从原始版本取值 if (target !== undefined) return target; target = websiteData.original; for (const key of propertyPath) { target = target[key]; } return target; } // 使用示例:传入属性路径数组 const secondaryHeadline = getElement('variant1', ['landingPage', 'secondaryHeadline']); // 返回变体的<h2>How are you?</h2> const primaryHeadline = getElement('variant1', ['landingPage', 'primaryHeadline']); // 返回原始版本的<h1>Hello to original</h1>
更优的工程化方案:初始化时深度合并配置
如果站点属性较多,每次取值都写兜底逻辑容易出错,可以在页面初始化时直接把变体配置和原始版本做深度合并,后续直接从合并后的对象取值即可,不需要任何额外判断:
// 可以用lodash的merge方法做深度合并,也可以自己实现简单的深度合并逻辑 import { merge } from 'lodash'; const getCurrentConfig = (version) => { // 原始版本作为基准,变体配置覆盖对应的增量属性 return merge({}, websiteData.original, websiteData[version] || {}); } // 使用示例 const currentConfig = getCurrentConfig('variant1'); console.log(currentConfig.landingPage.primaryHeadline); // 自动返回原始版本值 console.log(currentConfig.landingPage.secondaryHeadline); // 返回变体修改后的值
内容的提问来源于stack exchange,提问作者Nickfis
相关产品推荐
相关产品推荐

