一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript 中原始类型参数传递时的内存表现

时间:2026-07-04 12:58:46 编辑:袖梨 来源:一聚教程网

JavaScript原始类型传参是值传递,实参值被完整复制到函数栈帧新空间,与外部变量物理隔离;字符串、数字等不可变,所有“修改”实为创建新值,不影响原始变量。

JavaScript 中原始类型在参数传递时,内存表现非常直接:实参的值被完整复制一份,存入函数调用栈帧的新空间里,和外部变量物理隔离。

栈中独立存储,无共享也无指针

原始类型(number、string、boolean、null、undefined、symbol、bigint)的值直接存于栈内存。传参时,JS 在当前函数的栈帧中为形参分配一块新空间,并把实参的值原样拷贝过去——不是地址,不是引用,就是数据本身。

  • 比如 let a = "hello",传入函数后,形参 str 拥有自己的一份 "hello" 字符串副本,两者在栈中是两块不同的内存单元
  • 即使 astr 内容相同,它们的内存地址不同,修改其中一个对另一个毫无影响
  • 没有指针、没有引用计数、不涉及堆内存,也就没有垃圾回收压力

所有操作都作用于副本,原始值始终不变

因为字符串不可变、数字不可变,所有看似“修改”的操作(如 n += 1s.toUpperCase())实际都是创建新值并赋给局部变量,原始变量所在栈位置的数据纹丝不动。

  • function f(x) { x = x + 1; } → 只改了形参 x 所在栈位置的值
  • function g(s) { s = s.replace('a', 'b'); }s 指向一个新字符串,旧字符串仍由外部变量持有
  • 哪怕形参名和外部变量同名,比如 function h(a) { a = 99; },也只重写函数栈帧里的那个 a

与对象传参的本质区别:传的是什么

对象传参也是按值传递,但那个“值”是堆内存地址;原始类型传的“值”,是栈里实实在在的数据。这导致行为差异的根本原因不在“传参方式”,而在“所传之值的性质”。

立即学习“Java免费学习笔记(深入)”;

  • {x: 1}:形参拿到的是地址副本,通过它读写属性,会反映到同一块堆内存上
  • 42:形参拿到的是数字 42 的副本,再怎么算,外部的 42 还在原来栈位置安好无损
  • 判断是否影响外部,看操作目标:赋值给参数名(param = ...)一定不影响;操作参数属性或元素(param.prop = ...)才可能影响——但原始类型根本没有属性可操作

这种设计带来的实际好处

栈内独立存储让原始类型天然具备纯函数友好性:参数不可被意外篡改,副作用可控,逻辑可预测。

  • 函数返回新值,而非试图“修改入参”,是符合该机制的自然写法
  • 解构赋值、数组映射、状态更新等场景中,原始类型变量无需深浅拷贝顾虑——每次赋值就是一次干净的值拷贝
  • 调试时容易追踪:变量值就在栈里,不会因某处修改对象属性而“神秘变化”

热门栏目