You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 14:54:04