上一篇
按引用传递js
- 行业动态
- 2025-05-19
- 4
JS函数参数传递均为值,对象传引用,修改属性影响原对象,非
JavaScript 参数传递机制
基本概念
JavaScript 采用 “按共享传递”(Call by Sharing) 机制,既不是纯粹的按值传递,也不是按引用传递,具体表现如下:
数据类型 | 传递方式 | 特点 |
---|---|---|
原始类型 | 按值传递(实际是副本) | 函数内修改参数不影响外部变量 |
对象/数组 | 按引用传递(共享引用) | 函数内修改对象属性会影响外部对象 |
原始类型 vs 对象类型
原始类型(Number, String, Boolean, Undefined, Null, Symbol):
function testPrimitive(x) { x = 10; // 修改参数的值 } let a = 5; testPrimitive(a); console.log(a); // 输出 5(原始类型按值传递)
对象类型(Object, Array, Function):
function testObject(obj) { obj.prop = "new"; // 修改对象属性 } let person = { name: "Alice" }; testObject(person); console.log(person.name); // 输出 "new"(对象按引用传递)
常见误解
- 误解:所有参数都是按引用传递
现实:仅对象类型共享内存地址,原始类型传递的是值的副本 - 误解:函数内修改对象会创建新对象
现实:修改的是原对象的属性,未改变引用指向(obj = {}
才会改变引用)
关键示例对比
操作 | 原始类型 | 对象类型 |
---|---|---|
param = newValue | 不影响外部变量 | 不影响外部变量(仅修改引用) |
param.prop = value | 报错(不能赋值属性) | 修改外部对象属性 |
实际应用建议
- 需要修改对象:直接传递对象
function updateUser(user) { user.age += 1; }
- 避免副作用:克隆对象再操作
function cloneAndModify(obj) { const newObj = { ...obj }; newObj.name = "clone"; return newObj; }
相关问题与解答
问题1:如何判断参数是原始类型还是对象?
解答:
使用 typeof
或 Array.isArray()
判断:
typeof 123
→"number"
(原始类型)typeof {}
→"object"
(对象类型)Array.isArray([])
→true
(数组属于对象类型)
问题2:函数内部重新赋值参数会影响外部变量吗?
解答:
- 原始类型:不会(如
x = 5
) - 对象类型:不会(如
obj = {}
),但会改变参数引用指向,不影响原对象let obj = { a: 1 }; function reassign(o) { o = { b: 2 }; } // 仅修改局部引用 reassign(obj); console.log(obj); // 仍输出 {