如何将JS变量作为属性名代入JSON路径访问以优化重复代码
方案不生效的原因
- 无需调用
JSON.stringify():你需要的时间维度本身就是字符串值,直接赋值const z = 'weekly'即可,序列化反而会给值额外套一层引号,无法匹配对象的属性名。 - 点语法不支持变量作为属性名:你写
data[0].timeframes.z.current时,JS会尝试查找timeframes下名为z的属性,而非z变量存储的daily/weekly/monthly值,正确的动态属性访问要使用方括号语法:data[0].timeframes[z].current。
优化实现方案
你可以把重复逻辑抽成单个通用函数,同时用配置映射表进一步简化不同分类的重复赋值逻辑,最终只需要维护一份代码:
// 提前定义分类与对应DOM元素的映射关系,后续新增分类只需在这里更新配置即可 const categoryConfig = [ { index: 0, currentEl: currentWork, prevEl: previousWork }, { index: 1, currentEl: currentPlay, prevEl: previousPlay }, { index: 2, currentEl: currentStudy, prevEl: previousStudy }, { index: 3, currentEl: currentExercise, prevEl: previousExercise }, { index: 4, currentEl: currentSocial, prevEl: previousSocial }, { index: 5, currentEl: currentSelfcare, prevEl: previousSelfcare }, ] // 通用加载函数,仅需传入时间维度参数和对应历史周期文案 function loadTimeFrameData(timeFrame, prevLabel) { fetch("/data.json") .then(resp => resp.json()) .then(data => { // 循环处理所有分类,不用重复写赋值逻辑 categoryConfig.forEach(item => { const frameData = data[item.index].timeframes[timeFrame] item.currentEl.innerHTML = `${frameData.current}${hrs}` item.prevEl.innerHTML = `${prevLabel} - ${frameData.previous}${hrs}` }) }) eachBlock.forEach(el => el.classList.toggle('animatedBox')) }
按钮绑定逻辑
给你的日度、周度、月度按钮分别设置value属性为daily/weekly/monthly,点击时调用通用函数即可:
document.querySelectorAll('.time-btn').forEach(btn => { btn.addEventListener('click', () => { const timeFrame = btn.value // 不同维度对应不同的历史周期文案 const labelMap = { daily: lastDay, weekly: lastWeek, monthly: lastMonth } loadTimeFrameData(timeFrame, labelMap[timeFrame]) }) })
内容的提问来源于stack exchange,提问作者EDev
相关产品推荐
相关产品推荐

