JavaScript数据类型核心在于原始类型与引用类型的内存行为差异:原始类型(7种)存值于栈,赋值为值拷贝;引用类型(Object及其衍生)存地址于栈、数据于堆,赋值为地址拷贝,共享同一堆内存。

JavaScript 数据类型操作的核心,是分清“原始数据”和“对象”这两类本质不同的存在——不是语法差异,而是内存行为和赋值逻辑的根本区别。
原始数据:改自己,不影响别人
原始类型(string、number、boolean、null、undefined、symbol、bigint)的值直接存在栈内存里,变量存的就是值本身。所以赋值是“复制一份”,后续修改互不干扰。
- let a = 100; let b = a; → b 是 100 的副本,不是引用
- a = 200; console.log(b); // 还是 100
- 字符串、数字看似能“修改”,其实是创建新值:s = "a"; s += "b" 不是改原字符串,而是生成新字符串 "ab"
对象:改内容,大家跟着变
所有对象(包括数组 []、函数 function(){}、日期 new Date()、正则 /abc/、Map、Set 等)都属于引用类型。变量里存的只是指向堆内存中真实数据的地址。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- let obj1 = { x: 1 }; let obj2 = obj1; → obj2 和 obj1 指向同一块内存
- obj1.x = 99; console.log(obj2.x); // 输出 99
- 哪怕用 const 声明对象,也不能阻止属性被修改,因为 const 锁的是“地址不变”,不是“内容不可变”
怎么安全地复制一个对象?
想让两个变量彻底独立,就得做“拷贝”。浅拷贝只复制第一层,深拷贝才真正隔离所有嵌套层级。
立即学习“Java免费学习笔记(深入)”;
- 浅拷贝常用:{...obj}、Object.assign({}, obj)、arr.slice() 或 [...arr]
- 但它们对嵌套对象无效:let o = { a: { b: 1 } }; let c = { ...o }; c.a.b = 2 → o.a.b 也变成 2
- 深拷贝可用 JSON.parse(JSON.stringify(obj))(仅限纯数据,不支持函数、undefined、Date 等),或使用 structuredClone()(现代浏览器支持,推荐)
判断类型别只靠 typeof
typeof 对原始类型很准,但对 null 返回 "object",对数组、正则、日期也全返回 "object",容易误判。
- 判断是否为数组:Array.isArray(arr)
- 判断是否为日期:obj instanceof Date 或 Object.prototype.toString.call(obj) === "[object Date]"
- 通用安全判断:Object.prototype.toString.call(value) 可区分所有内置类型,比如返回 "[object Array]"、"[object RegExp]"

















