在 JavaScript 中,按值传递和按引用传递的概念很重要。基本类型(如数字、字符串、布尔值)是按值传递的,而对象类型(如数组、对象)是按引用传递的。
1. 按值传递(Pass by Value)
对于基本数据类型(如number
、string
、boolean
、undefined
、null
、symbol
),JavaScript 是按值传递的。即,在函数中传递这些类型的变量时,传递的是它们的值的副本,不会影响原始变量。
示例:
1 2 3 4 5 6 7 8 |
function modifyValue(x) { x = 10; console.log("Inside function:", x); // 输出 10 } let num = 5; modifyValue(num); console.log("Outside function:", num); // 输出 5(未被修改) |
- 解释:在这个例子中,
num
是一个基本类型(number
),传递给函数modifyValue
后,在函数内部对x
的修改不会影响外部的num
,因为num
的值是按值传递的(即x
是num
的一个副本)。
2. 按引用传递(Pass by Reference)
对于复杂数据类型(如object
、array
、function
),JavaScript 是按引用传递的。传递的不是对象的副本,而是对象的引用,因此在函数内部修改对象的属性会影响原始对象。
示例:
1 2 3 4 5 6 7 8 |
function modifyObject(obj) { obj.name = "Alice"; console.log("Inside function:", obj); // 输出 { name: "Alice" } } let person = { name: "Bob" }; modifyObject(person); console.log("Outside function:", person); // 输出 { name: "Alice" }(被修改) |
- 解释:在这个例子中,
person
是一个对象类型,传递给modifyObject
函数时,传递的是对象的引用,因此在函数内部修改对象属性会影响到原始对象。
3. 按引用传递但不改变引用本身
虽然对象是按引用传递的,但如果你试图在函数内改变引用本身(即将它指向一个新对象),那么这种改变不会影响外部的对象引用。
示例:
1 2 3 4 5 6 7 8 |
function replaceObject(obj) { obj = { name: "Charlie" }; // 尝试用新对象替换原对象 console.log("Inside function:", obj); // 输出 { name: "Charlie" } } let person = { name: "Bob" }; replaceObject(person); console.log("Outside function:", person); // 输出 { name: "Bob" }(未被替换) |
- 解释:在这个例子中,虽然传递的是引用,但在函数内部把
obj
重新赋值为一个新对象时,改变的只是obj
本身的引用,而不会影响外部的person
。
总结
改变引用不会影响外部对象:在函数内部将引用重新赋值时,外部对象的引用不会受影响。
按值传递:基本类型的值传递,修改不会影响原始值。
按引用传递:对象类型的引用传递,修改对象的属性会影响原始对象。