JavaScript函数传参的运行机制解析

函数传参的运行结果取决于传递的参数类型以及函数内部对这些参数的处理方式。以下是几种常见的传参情况及其运行结果的解释:
1. 基本类型(Primitive Types)传参
- 示例:
function changeValue(num) { num = 10; } let a = 5; changeValue(a); console.log(a); // 输出: 5
- 解释:
- 在JavaScript中,基本类型(如
number
、string
、boolean
等)是按值传递的。 - 当
a
传递给changeValue
函数时,函数内部操作的是a
的一个副本,而不是a
本身。 - 因此,函数内部对
num
的修改不会影响外部的a
。
- 在JavaScript中,基本类型(如
2. 引用类型(Reference Types)传参
- 示例:
function changeArray(arr) { arr.push(4); } let myArray = [1, 2, 3]; changeArray(myArray); console.log(myArray); // 输出: [1, 2, 3, 4]
- 解释:
- 引用类型(如
object
、array
、function
等)是按引用传递的。 - 当
myArray
传递给changeArray
函数时,函数内部操作的是myArray
的引用,而不是副本。 - 因此,函数内部对
arr
的修改会直接影响外部的myArray
。
- 引用类型(如
3. 对象属性修改
- 示例:
function changeObject(obj) { obj.name = "Alice"; } let person = { name: "Bob" }; changeObject(person); console.log(person.name); // 输出: "Alice"
- 解释:
- 对象作为参数传递时,传递的是对象的引用。
- 函数内部对对象属性的修改会直接影响外部的对象。
4. 重新赋值对象引用
- 示例:
function reassignObject(obj) { obj = { name: "Alice" }; } let person = { name: "Bob" }; reassignObject(person); console.log(person.name); // 输出: "Bob"
- 解释:
- 虽然对象是按引用传递的,但在函数内部重新赋值
obj
时,obj
指向了一个新的对象。 - 这个操作不会影响外部的
person
对象,因为obj
只是person
的一个引用副本。
- 虽然对象是按引用传递的,但在函数内部重新赋值
5. 默认参数
- 示例:
function greet(name = "Guest") { console.log(`Hello, ${name}!`); } greet(); // 输出: "Hello, Guest!" greet("Alice"); // 输出: "Hello, Alice!"
- 解释:
- ES6引入了默认参数,允许在函数定义时为参数指定默认值。
- 如果调用函数时没有传递该参数,或者传递了
undefined
,则使用默认值。
6. 剩余参数(Rest Parameters)
- 示例:
function sum(...numbers) { return numbers.reduce((acc, num) => acc + num, 0); } console.log(sum(1, 2, 3, 4)); // 输出: 10
- 解释:
- 剩余参数允许将不定数量的参数表示为一个数组。
- 在函数内部,
numbers
是一个包含所有传递参数的数组。
7. 解构赋值传参
- 示例:
function printUser({ name, age }) { console.log(`Name: ${name}, Age: ${age}`); } let user = { name: "Alice", age: 25 }; printUser(user); // 输出: "Name: Alice, Age: 25"
- 解释:
- 解构赋值允许从对象或数组中提取值并赋值给变量。
- 在函数参数中使用解构赋值可以方便地提取对象中的特定属性。
总结
- 基本类型:按值传递,函数内部修改不会影响外部变量。
- 引用类型:按引用传递,函数内部修改会影响外部对象。
- 默认参数:允许为参数指定默认值。
- 剩余参数:允许将不定数量的参数表示为数组。
- 解构赋值:方便地从对象或数组中提取值。
理解这些传参机制对于编写可预测和可维护的代码至关重要。