在 JavaScript 中,变量的传递方式常常让人困惑。很多人会说“基本类型是值传递,对象是引用传递”,但其实更准确的说法是:JavaScript 始终是值传递,但对于对象来说,这个‘值’是一个指针(内存地址)的副本。
一、基本类型的值传递
对于原始数据类型(如 Number
、String
、Boolean
、null
、undefined
、Symbol
、BigInt
),函数传参时传递的是变量的实际值的拷贝。
示例:
let a = 10;
function change(x) {
x = 20;
}
change(a);
console.log(a); // 输出 10
- 函数内部对
x
的修改不会影响外部的a
。 - 这就是典型的值传递。
二、对象类型的“指针传递”
对于对象类数据类型(包括对象Object{}
、数组[]
、函数等),函数传参时传递的是该对象在堆内存中的地址(指针)的副本。也就是说,函数内部和外部都指向同一个对象。
-
修改属性会影响原对象
-
重新赋值不会影响原对象
示例1:修改属性会影响原对象
let obj = { value: 10 };
function modify(o) {
o.value = 20;
}
modify(obj);
console.log(obj.value); // 输出 20
- 因为
o
和obj
指向的是同一个内存地址,所以通过o
修改对象属性会影响原对象。
示例2:重新赋值不会影响原对象
let obj = { value: 10 };
function reassign(o) {
o = { value: 20 };
}
reassign(obj);
console.log(obj.value); // 输出 10
- 此时
o
被赋予了一个新的对象地址,不再指向原来的obj
,所以外部的obj
不受影响。
这说明:JS 并不是真正的引用传递,而是将“指针”作为值来传递。