智享教程网
白蓝主题五 · 清爽阅读
首页  > 日常经验

处理JSON多层嵌套,其实没那么复杂

做前端开发或者写接口对接的时候,经常会遇到一种让人头大的数据结构——JSON多层嵌套。比如你从后台拿到一段数据,展开一看,里面套着对象,对象里又套数组,数组里还有对象,一层接一层,看得眼花缭乱。

一个真实的场景

前几天我帮同事调一个用户信息接口,返回的数据长这样:

{
  "status": "success",
  "data": {
    "user": {
      "id": 1001,
      "name": "张伟",
      "profile": {
        "age": 28,
        "address": {
          "city": "杭州",
          "district": "西湖区"
        }
      },
      "orders": [
        {
          "order_id": "O20240401001",
          "items": [
            { "product": "咖啡机", "price": 599 }
          ]
        }
      ]
    }
  }
}

想取用户的所在城市?得这么写:response.data.user.profile.address.city。要是哪一层拼错了,或者某个字段是 null,程序就可能直接报错。

怎么安全地读取嵌套数据?

直接用点操作符风险太高。更稳妥的做法是加判断,比如:

let city = response && response.data && response.data.user && 
           response.data.user.profile && response.data.user.profile.address ? 
           response.data.user.profile.address.city : null;

虽然啰嗦,但至少不会崩溃。不过写多了真的累。

现在很多人会用解构赋值配合默认值来简化:

const { data: { user: { profile: { address: { city } = {} } = {} } = {} } = {} } = response;

看起来有点绕,但一旦习惯,写起来还挺顺手。记得给每一层可能缺失的对象设空对象默认值,避免引用错误。

工具函数也能帮大忙

如果你经常处理这种结构,可以封装一个取值函数:

function get(obj, path, defaultValue = null) {
  const keys = path.split('.');
  let result = obj;
  for (let key of keys) {
    if (result == null || typeof result !== 'object') return defaultValue;
    result = result[key];
  }
  return result !== undefined ? result : defaultValue;
}

// 使用方式
const city = get(response, 'data.user.profile.address.city');

路径写成字符串,清晰又不容易出错。类似的方法在 lodash 里也有,叫 _.get,可以直接用。

嵌套太深?可能是设计问题

有时候数据嵌得太深,不是代码的问题,而是接口设计可以优化。比如“订单里的商品”本可以扁平化处理,没必要层层包裹。跟后端同事沟通一下,看看能不能调整结构,减少不必要的层级。

另外,前端展示时也可以考虑做一次数据整理,把常用字段提前:

const userInfo = {
  name: response.data.user.name,
  city: response.data.user.profile.address.city,
  latestOrder: response.data.user.orders[0]?.order_id
};

这样后续用起来就轻松多了。

JSON多层嵌套并不可怕,关键是怎么应对。掌握几种取值技巧,再结合实际业务调整数据结构,慢慢就习惯了。