如何根据字符串数组生成对象嵌套属性的括号表示法实现读写操作
基于属性路径数组访问深层对象属性的实现方案
核心思路是通过Array.prototype.reduce遍历属性路径数组,逐层访问对象嵌套层级,分别实现读取和赋值逻辑即可。
读取属性值
遍历属性数组逐层向下取值,配合可选链语法可以避免中间层级不存在时的报错:
const deepProperties = ['contactPerson', 'firstName'] const unknown = { contactPerson: { firstName: 'Jane' } } function getDeepValue(obj, propPath) { return propPath.reduce((currentLevel, prop) => currentLevel?.[prop], obj) } // 测试读取 console.log(getDeepValue(unknown, deepProperties)) // 输出 'Jane'
赋值属性值
赋值逻辑需要先遍历到属性路径的倒数第二层拿到父对象,再对最后一个属性执行赋值操作:
基础版(要求中间层级已存在)
function setDeepValue(obj, propPath, value) { // 取路径的最后一个属性名 const finalProp = propPath[propPath.length - 1] // 遍历到倒数第二层,拿到父级对象 const parentLevel = propPath.slice(0, -1).reduce((currentLevel, prop) => currentLevel[prop], obj) // 执行赋值 parentLevel[finalProp] = value } // 测试赋值 setDeepValue(unknown, deepProperties, 'John') console.log(unknown.contactPerson.firstName) // 输出 'John'
进阶版(自动创建不存在的中间层级)
如果需要支持中间层级不存在时自动创建空对象避免报错,可以调整reduce的逻辑:
function setDeepValueAuto(obj, propPath, value) { const finalProp = propPath[propPath.length - 1] const parentLevel = propPath.slice(0, -1).reduce((currentLevel, prop) => { // 层级不存在则初始化为空对象 if (!currentLevel[prop]) currentLevel[prop] = {} return currentLevel[prop] }, obj) parentLevel[finalProp] = value } // 测试自动创建层级 const testObj = {} setDeepValueAuto(testObj, ['a', 'b', 'c'], 123) console.log(testObj.a.b.c) // 输出 123
注意:如果需要兼容ES2022以下的环境,避免使用
Array.prototype.at方法,用数组下标取最后一位即可。
内容的提问来源于stack exchange,提问作者Alexander Zeitler
相关产品推荐
相关产品推荐

