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' 共同作用的结果。

相关推荐
用户84921073693806 分钟前
Skywalking 部署
后端
bug菌7 分钟前
🤔领导突然考我Spring中的注解@Bean,它是做什么用的?我...
java·后端·spring
小高0071 小时前
协商缓存和强缓存
前端·javascript·面试
前端Hardy1 小时前
HTML&CSS&JS:超酷炫的一键登录页面
前端·javascript·css
aiopencode1 小时前
移动端网页调试实战,触摸事件穿透与点击冲突问题的定位与优化
后端
菜鸟Debug1 小时前
🚀 Redisson 分布式锁源码解析:从加锁到解锁的完整流程
后端
该用户已不存在1 小时前
2025年,Javascript后端应该用 Bun、Node.js 还是 Deno?
javascript·后端
余_弦1 小时前
区块链钱包开发(十八)—— 构建批准控制器(ApprovalController)
javascript·区块链·以太坊
拭心1 小时前
一键生成 Android 适配不同分辨率尺寸的图片
android·开发语言·javascript
sorryhc1 小时前
CSR秒开有可能么?(附AI驱动学习实践推理过程)
前端·javascript·ai编程