JavaScript如何使用点分隔字符串读取深层对象属性实现可复用排序
实现方案
你要的效果不能直接通过obj['a.b']的原生语法实现,JS方括号语法会把传入的字符串整体作为单一属性名查找,不会自动解析点分隔的嵌套路径,需要自己封装逻辑实现。
1. 封装深层属性取值工具
核心逻辑是把点分隔的路径字符串拆分为属性数组,逐层遍历对象取值:
function getNestedValue(obj, path) { const keyList = path.split('.'); return keyList.reduce((currentObj, key) => { // 中间属性不存在时直接返回undefined,避免报错 return currentObj && Object.hasOwn(currentObj, key) ? currentObj[key] : undefined; }, obj); }
使用示例:
// 用你给出的players数组测试 console.log(getNestedValue(players[0], 'points.current')); // 输出100 console.log(getNestedValue(players[1], 'points.total')); // 输出500
2. 封装通用排序方法
基于上面的取值工具,封装可传入嵌套路径的排序函数,同时支持自定义排序方向:
/** * 根据嵌套属性对对象数组排序 * @param {Array} arr 要排序的对象数组 * @param {String} path 点分隔的嵌套属性路径 * @param {String} order 排序方向:desc降序/asc升序,默认desc * @returns {Array} 排序后的新数组(不会修改原数组) */ function sortByNestedProp(arr, path, order = 'desc') { // 浅拷贝原数组,避免sort原地修改原数组 return [...arr].sort((a, b) => { const valA = getNestedValue(a, path); const valB = getNestedValue(b, path); // 数值类型排序 if (typeof valA === 'number' && typeof valB === 'number') { return order === 'desc' ? valB - valA : valA - valB; } // 字符串类型排序(兼容按名字排序等场景) if (typeof valA === 'string' && typeof valB === 'string') { const strCompareRes = valA.localeCompare(valB); return order === 'desc' ? -strCompareRes : strCompareRes; } // 其他类型或者属性不存在的情况,默认优先级相同 return 0; }); }
使用示例:
// 按points.current降序排序 const sortedByCurrent = sortByNestedProp(players, 'points.current'); // 按points.total升序排序 const sortedByTotalAsc = sortByNestedProp(players, 'points.total', 'asc'); // 按name升序排序 const sortedByName = sortByNestedProp(players, 'name', 'asc');
其他可选思路
如果你的运行环境支持可选链语法,且不需要动态传入路径的场景,也可以直接用a?.points?.current写法,但是要做通用封装的话,上述拆分路径的方案适配性更强。
内容的提问来源于stack exchange,提问作者T3rr11
相关产品推荐
相关产品推荐

