如何在JavaScript中根据数组存储的路径访问对象属性?
问题:根据字符串路径访问JavaScript对象中的数据
我做了个用来对比API温度数据的应用,一开始给每个API写了单独的处理函数,代码能正常运行,但存在大量重复代码:
async function prepData(n) { const a = []; if ((n == 0)) { const json = await firstAPI(); for (var i = 0; i <= c; i++) { a.push(json.shortIntervals[i].temperature.value); } console.log(a); return a; } else { const json = await secondAPI(); for (var i = 0; i <= c; i++) { a.push( json.properties.timeseries[i].data.instant.details.air_temperature, ); } console.log(a); return a; } }
后来我重构代码,将API请求合并为fetching(n)函数,通过参数n选择对应API地址,但遇到了数据访问路径的问题。当前代码如下:
const dataLocation = ['json.first.api.path', 'json.seccond.api.path'] async function prepData(n) { const a = []; const json = await fetching(n); for (var i = 0; i <= c; i++) { a.push(dataLocation[n]); } console.log(a); return a; }
我把数据路径存储在数组中,但直接使用dataLocation[n]只会将路径字符串存入新数组,无法实际访问对象中的对应数据。请问如何让JavaScript根据数组中定义的路径访问对象数据?
注:变量c为提前定义的数值,用于控制从API获取的数据量。
解决方案
方法1:拆分路径字符串,逐层访问对象
先修正dataLocation里的实际路径(注意你拼写错误的seccond应该改为second),然后通过工具函数拆分路径字符串,逐层遍历对象属性:
// 替换为实际的路径模板,包含[i]作为索引占位符 const dataLocation = [ 'shortIntervals[i].temperature.value', 'properties.timeseries[i].data.instant.details.air_temperature' ]; // 工具函数:根据路径字符串、目标对象和索引获取对应数据 function getValueByPath(obj, pathStr, index) { // 替换路径中的[i]为实际索引,再按.拆分路径 const pathSegments = pathStr.replace('[i]', `[${index}]`).split('.'); let current = obj; for (const segment of pathSegments) { // 处理带数组索引的片段,比如shortIntervals[0] if (segment.includes('[')) { const [propName, idx] = segment.split(/\[|\]/).filter(Boolean); current = current[propName][idx]; } else { current = current[segment]; } } return current; } async function prepData(n) { const a = []; const json = await fetching(n); const targetPath = dataLocation[n]; for (let i = 0; i <= c; i++) { a.push(getValueByPath(json, targetPath, i)); } console.log(a); return a; }
方法2:使用函数代替字符串路径(推荐)
相比字符串路径,直接存储数据提取函数更直观安全,无需处理字符串解析的逻辑:
// 存储对应每个API的数据提取逻辑函数 const dataExtractors = [ // 第一个API的提取逻辑 (json, i) => json.shortIntervals[i].temperature.value, // 第二个API的提取逻辑 (json, i) => json.properties.timeseries[i].data.instant.details.air_temperature ]; async function prepData(n) { const a = []; const json = await fetching(n); const extractData = dataExtractors[n]; for (let i = 0; i <= c; i++) { a.push(extractData(json, i)); } console.log(a); return a; }
这种方式代码可读性更高,也能避免路径字符串拼写错误带来的问题,是更优的重构方案。
内容的提问来源于stack exchange,提问作者jes
相关产品推荐
相关产品推荐

