在 JavaScript 中,理解变量的访问方式——按值访问和按引用访问——是理解语言数据结构和行为的关键。这两种方式主要取决于变量的数据类型。
- 按值访问(Pass by Value)
在 JavaScript 中,原始类型(Primitive Types)的数据是按值访问的。原始类型包括:Number
、String
、Boolean
、Null
、Undefined
、Symbol
和 BigInt
。当你把一个原始类型的值赋给另一个变量时,实际上是在内存中创建了这个值的一个新副本,并且把这个新副本的地址赋给了新的变量。因此,改变新变量的值不会影响原始变量的值。
例如:
let a = 5;
let b = a; // b 得到了 a 的一个副本,即 5
b = 10; // 改变 b 的值,a 的值不变
console.log(a); // 输出 5
- 按引用访问(Pass by Reference)
在 JavaScript 中,对象类型(Object Types)的数据(包括数组和函数)是按引用访问的。对象类型的变量存储的是对象的引用地址,而不是对象本身。当你把一个对象类型的变量赋给另一个变量时,实际上是把对象的引用地址复制了一份给新的变量。因此,通过新变量和原始变量访问的是同一个对象,改变对象的状态会在所有引用这个对象的变量中反映出来。
例如:
let obj1 = { value: 1 };
let obj2 = obj1; // obj2 得到了 obj1 的引用地址
obj2.value = 2; // 通过 obj2 改变对象的值,obj1 也会受到影响
console.log(obj1.value); // 输出 2
需要注意的是,虽然对象类型是按引用访问的,但当你尝试把一个对象类型的变量完全赋给另一个新的对象时,并不会改变原始对象的引用。这是因为赋值操作创建了一个新的对象,并把原始对象的属性值复制到了新对象中。这个过程被称为浅拷贝(Shallow Copy)。
例如:
let obj1 = { value: 1 };
let obj2 = { ...obj1 }; // 使用展开运算符进行浅拷贝
obj2.value = 2; // 改变 obj2 的值,obj1 的值不变
console.log(obj1.value); // 输出 1
总结来说,在 JavaScript 中,原始类型是按值访问的,而对象类型是按引用访问的。理解这一点有助于你更好地掌握 JavaScript 中的数据操作和行为。