原始类型存值于栈,赋值和比较均基于值本身;复杂类型存地址于栈、数据存于堆,赋值和比较均基于引用地址,直接影响复制与传参行为。

JavaScript 中原始类型(基本类型)和复杂类型(引用类型)最核心的区别,在于它们在内存中存放的位置和方式不同:原始类型直接存值,复杂类型存地址。
原始类型存在栈里,值是“实打实”的
原始类型包括 number、string、boolean、undefined、null、symbol、bigint。它们的值大小固定、结构简单,JS 引擎会把它们直接放进栈内存中——就像把一张写好数字的纸条塞进抽屉格子,每个变量独占一份内容。
- 赋值时拷贝的是整个值,比如
let a = 10; let b = a;,b得到的是10的副本,改b不影响a - 比较时比的是值本身:
10 === 10是true,"abc" === "abc"也是true - 栈内存自动管理,函数执行完,局部原始变量就释放了
复杂类型存在堆里,变量只存“门牌号”
复杂类型包括 object、array、function、date、regexp、map、set 等。它们的内容大小不固定、结构可变,JS 引擎会把实际数据放在堆内存中,而变量本身只在栈里存一个指向堆中那块数据的地址——就像通讯录里记的不是朋友本人,而是他家的住址。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 赋值时拷贝的是地址,比如
let obj1 = {x: 1}; let obj2 = obj1;,obj1和obj2指向堆中同一块区域,改obj2.x,obj1.x也会变 - 比较时比的是地址,不是内容:
{x:1} === {x:1}是false,因为两个对象在堆里占了不同位置,地址不同 - 堆内存靠垃圾回收器(GC)自动清理,当没有变量再引用某块堆数据时,它才可能被回收
这种差异直接影响日常编码行为
你写 const arr = [1,2,3]; const newArr = arr;,看似复制数组,其实只是复制了指针。后续对 newArr.push(4),arr 也变成 [1,2,3,4]。要真正复制内容,得用展开运算符 [...arr]、Array.from() 或 JSON.parse(JSON.stringify())(注意后者有局限)。
同理,函数传参时,传原始类型是“送复印件”,传对象是“给钥匙”。理解这点,才能避开修改意外共享状态的坑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










