Map穿越JSON边境后惨遭“洗白”?前端:我只认识Object!

后端明明返回的数据格式是Map的,为啥我接到以后格式变成了Object?

事情的起因是这个接口返回的是一个Map然后前端接受以后打印出来的是一个ojbect

前端小伙伴(比如用 JavaScript)兴冲冲地调用这个接口:

javascript 复制代码
fetch('/getEquipment')
  .then(response => response.json())
  .then(data => {
    console.log("deviceRunState类型:"  + typeof res.data.deviceRunState);
    console.log(res.data.deviceRunState);
  });

运行结果往往令人困惑:

明明 Java 代码里清清楚楚写着返回 Map<String, Object>,怎么一到前端就成了一个普普通通的 object?这个看似简单的现象背后,其实藏着两个关键的技术真相。

原因1:JSON的原因

当你的 Java Map 离开后端,准备前往前端时,它必须进行一次长途运输。这个运输工具就是 JSON 。JSON 是前后端数据交换的通用语言,但它有个特点:只关心数据的结构和值,完全不在乎数据在原始语言中的具体类型名称。

  • 后端打包(序列化): Spring Boot(或其他框架)使用如 Jackson 的库,把 Java Map 对象仔细拆解。它记录下所有的键值对(key-value) JSON 字符串里,没有任何地方标注这是一个 HashMap" 。它只描述了这里有一个对象,里面有键以及对应的值。值是一个数组(用 [] 表示)。原始类型(字符串、数字、布尔值、null)和它们的值会被保留,但容器类型(Map, List, Set 等)的具体类型信息在转换过程中被彻底丢弃了。JSON 标准本身根本不支持记录这种元信息。

原因2:JavaScript 可能不认识Map

当前端 JavaScript 收到这个 JSON 字符串,它需要把它变回自己能操作的数据。它使用 JSON.parse() 方法:

javascript 复制代码
runstate_map = new Map(Object.entries(res.data.deviceRunState));
console.log(typeof runstate_map); // 输出: "object"
//然后获取runstate_map的值的时候,就可以直接使用map.get("")就行了
 if(runstate_map!=null){
    var runstate = runstate_map.get(item.identifier);
    console.log("runstate:" + runstate);
  • 遇到 {}: 它就创建一个新的 JavaScript 普通对象 。这种对象的核心功能就是存储键值对,和 Java 的 Map 在基础功能上非常相似(增删改查键值对)。
  • 遇到 []: 它就创建一个 JavaScript 数组 (Array)。
  • 遇到字符串、数字等: 就创建对应的 JavaScript 基本类型。

核心问题在于:JavaScript 中没有一个叫做 Map 的基础数据类型来表示这种键值对集合! 在 JavaScript 的世界观里:

  1. typeof 操作符: 对于任何非基本类型(非 string, number, boolean, symbol, undefined, null)的值,typeof 返回的结果都是"object"。
  2. ES6 的 Map: 现代 JavaScript (ES6) 确实引入了 Map 类型,它比普通对象更适合某些键值对场景(比如键可以是任意类型、保持插入顺序等)。但是,JSON.parse() 默认行为绝对不会把 JSON 对象 {} 解析成 JavaScript 的 Map 实例! 它只会解析成普通的 JavaScript 对象。

所以,当你在前端执行 typeof data 时,data 就是 创建出来的一个标准 JavaScript 普通对象,typeof 报告它是 "object" 是完全准确且符合语言规范的。它确实就是一个 Object,而不是一个 Java 后端返回的Map格式。

总结

Java 后端的 Map 经过 JSON 序列化"运输"后,丢失了"Map"这个类型标签,变成了只描述结构的纯数据。前端 JavaScript 根据 JSON的语法,自然创建出它最基础的对象类型------普通对象。JavaScript 的 typeof 运算符诚实地将其报告为 "object"。这不是 bug,而是 JSON 作为通用数据格式的固有特性(不保留语言特定类型)与 JavaScript 类型系统(typeof 对非原始类型返回 'object') 共同作用的结果。

相关推荐
程序员大阳3 小时前
HTML+CSS+JS对话式实战(5)-活动管理页之查看报名名单的实现
javascript·css·html·查看报名名单
Gopher_HBo3 小时前
Go CPU 剖析的"地基":信号、CAS、写屏障、无锁环形缓冲
后端
panbook3 小时前
从0到1实现一个分布式时序数据库(二):写入成功之后,如何用 WAL 找回数据
后端
Swot3 小时前
上传一张 4MB 图片,我先后撞上了三层请求体限制
后端
IT_陈寒4 小时前
Vite的HMR把我整不会了:一个生产环境的热更新坑
前端·人工智能·后端
OLRainM4 小时前
实习复盘:大模型网关渠道质量评分实战(二)—— 报错了到底算谁的锅?流式归因与 Token 补账踩过的 8 个真坑
后端
梦想恒远4 小时前
Spring Boot + LangChain4j 统计 token 成本:ChatModelListener 实测与单价口径
spring boot·后端
努力的小郑5 小时前
数据查到了,回答去哪儿了?一次百炼 + LangChain 排查实录
后端·langchain·agent
新*5 小时前
从一段 WebSocket 代码聊开:bytes 不是 zlib、binaryType 决定一切,15MB 大消息的零拷贝优化
javascript·python·websocket·性能优化·blob·zlib·arraybuffer
isfox6 小时前
Python 虚拟环境:别再把所有项目塞进一个"大仓库"了
后端