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

相关推荐
Stringzhua12 小时前
setup函数相关【3】
前端·javascript·vue.js
neon120412 小时前
解决Vue Canvas组件在高DPR屏幕上的绘制偏移和区域缩放问题
前端·javascript·vue.js·canva可画
考虑考虑12 小时前
Redis8中的布谷鸟过滤器
redis·后端·程序员
Sammyyyyy12 小时前
Node.js 做 Web 后端优势为什么这么大?
开发语言·前端·javascript·后端·node.js·servbay
重庆穿山甲13 小时前
Cola架构深度解析:企业级应用架构设计指南
后端
IT_陈寒13 小时前
🔥5个必学的JavaScript性能黑科技:让你的网页速度提升300%!
前端·人工智能·后端
Bling_Bling_113 小时前
面试常考:js中 Map和 Object 的区别
开发语言·前端·javascript
前端小巷子13 小时前
JS实现丝滑文字滚动
前端·javascript·面试
写不出来就跑路14 小时前
基于 HTML+CSS+JavaScript 的薪资实时计算器(含本地存储和炫酷动画)
javascript·css·html