如何在JavaScript中根据嵌套键字符串获取对象对应值?
问题:如何从嵌套对象中通过带点的键获取对应值?
我正在编写一段小型JavaScript代码片段,目标是根据指定的键从对象中返回对应值,该对象支持嵌套结构。以下是我的代码:
let obj = { "name": "Family", "count": 6, "children": { "name": "Jim", "age": "24", "address": { "street": "5th ave", "state": "NY", "country":"US" } }, "parents": { "name": "John", "age": "45", "address": { "street": "New brew st", "state": "CA", "country":null } } }; const getData = (obj) => { let jsonString = obj; let keys = ["name", "count","children.address.street"]; let returnString = ""; keys.forEach((item) => { returnString += buildString(item, jsonString) + "$$"; }) return returnString.replace(/(\$\$)*$/, ""); } const buildString = (keyIn, data) => { var value = ''; if (keyIn.includes('.')) value = splitAndReturn(keyIn, data); else value = data[keyIn] ? data[keyIn] : null; return `${keyIn}###${value}`; }; const splitAndReturn = (keyIn, obj) => { let nKeyArr = keyIn.split('.'); let buildString = 'obj'; nKeyArr.forEach(item => { buildString += `['${item}']`; }); let nKey = buildString; return (nKey); } console.log(getData(obj));
我的思路是:当键中包含“.”时,调用splitAndReturn函数将其转换为['']格式的访问路径,最终返回obj['xxx']['xxx']形式的结果。例如传入“children.name”时应返回“Jim”,传入“children.address.country”时应返回“US”。但目前splitAndReturn函数仅返回了字符串形式的访问路径,无法获取到键对应的实际值,请问该如何修改代码以实现预期功能?
解决方案
嗨,我明白你的问题了——你现在的splitAndReturn只是把键拼接成了访问路径的字符串,但并没有真正去读取对象的属性值。而且直接用eval执行这个字符串还存在安全风险(如果键的来源不可信的话),所以咱们换一种更安全可靠的方式来实现:
方案1:迭代遍历嵌套属性
修改splitAndReturn函数,通过循环一步步深入对象层级,直到找到目标属性:
const splitAndReturn = (keyIn, obj) => { let current = obj; const keyParts = keyIn.split('.'); for (const key of keyParts) { // 检查当前层级是否存在该属性,或者当前值是否不是对象(避免报错) if (!current || typeof current !== 'object' || !(key in current)) { return null; } current = current[key]; } // 处理null/undefined的情况,和你原代码逻辑保持一致 return current ?? null; };
方案2:递归遍历嵌套属性
如果你更喜欢递归的写法,也可以这样实现:
const splitAndReturn = (keyIn, obj) => { const [firstKey, ...remainingKeys] = keyIn.split('.'); // 边界检查:当前对象不存在或没有该属性 if (!obj || typeof obj !== 'object' || !(firstKey in obj)) { return null; } // 如果已经是最后一个键,直接返回对应值 if (remainingKeys.length === 0) { return obj[firstKey] ?? null; } // 递归处理剩余的键路径 return splitAndReturn(remainingKeys.join('.'), obj[firstKey]); };
额外优化:简化getData函数
另外,你可以把getData里的字符串拼接逻辑改成更简洁的数组map+join方式,避免最后替换多余$$的步骤:
const getData = (obj) => { const keys = ["name", "count","children.address.street"]; // 用map生成每个键对应的结果字符串,再用$$连接 return keys.map(key => buildString(key, obj)).join('$$'); };
测试效果
修改完成后,运行console.log(getData(obj))会输出:
name###Family$$count###6$$children.address.street###5th ave
完全符合你预期的功能,不管是单层键还是带点的嵌套键,都能正确返回对应的属性值啦!
内容的提问来源于stack exchange,提问作者user3872094
相关产品推荐
相关产品推荐

