JavaScript参数传递_值引用机制

JavaScript函数传参是按值传递引用。基本类型传递值的副本,修改不影响原变量;对象类型传递引用地址的副本,可修改对象属性但重新赋值参数不影响原引用。

JavaScript中的参数传递机制常被误解为“值传递”或“引用传递”的简单分类,但实际上它遵循一种更准确的说法:按值传递引用,也叫引用的值传递

基本类型:真正的值传递

当函数接收一个基本类型(如 number、string、boolean、null、undefined、symbol)作为参数时,传入的是该值的一个副本。

说明:
  • 在函数内部修改参数变量,不会影响外部原始变量。
  • 因为传递的是“值的拷贝”,两者完全独立。

示例:

function changeValue(a) {
  a = 10;
  console.log(a); // 输出 10
}
let num = 5;
changeValue(num);
console.log(num); // 输出 5 —— 原值未变

对象类型:传递的是引用的值

当参数是对象(包括数组、函数、普通对象)时,JavaScript传递的是该对象在堆内存中地址的副本,也就是“引用的值”。

关键点:
  • 函数内部可以通过这个引用访问并修改对象的实际内容。
  • 但如果重新赋值参数变量,只会改变局部引用,不影响原引用。

示例1:修改对象属性

function changeObj(obj) {
  obj.name = "changed";
  console.log(obj.name); // 输出 "changed"
}
let person = { name: "original" };
changeObj(person);
console.log(person.name); // 输出 "changed" —— 原对象被修改

示例2:重新赋值参数

function reassignObj(obj) {
  obj = { name: "new" };
  console.log(obj.name); // 输出 "new"
}
let person = { name: "original" };
reassignObj(person);
console.log(person.name); // 输出 "original" —— 原对象未受影响

如何理解“按值传递引用”?

可以把变量看作一个“指针盒子”:

  • 基本类型:盒子里装的是实际的值。
  • 对象类型:盒子里装的是内存地址(引用)。
  • 函数传参时,把这个“盒子的内容”复制一份传进去。

所以即使传的是引用,也只是复制了地址值,不是共享同一个盒子。

实际开发中的注意事项

  • 想避免意外修改对象?使用 Object.assign({}, obj){...obj} 创建浅拷贝。
  • 需要深拷贝时可考虑 JSON.parse(JSON.stringify(obj))(注意局限)或使用专门库。
  • 理解这一点有助于排查“为什么我的对象在函数里变了”的问题。

基本上就这些。不复杂但容易忽略细节。