JavaScript中修改函数形参为何无法改变外部原变量值
为什么函数内修改参数无法改变外部原始类型变量
JavaScript中所有原始类型(数字、字符串、布尔值、null、undefined、Symbol、BigInt)的参数传递都是按值传递,这是第一个示例不生效的核心原因。
当你把外部变量b作为实参传入函数t时,引擎会把b当前存储的值3拷贝一份,赋值给函数内部的形参n。这时候n是函数作用域下的独立局部变量,和外部的b没有任何绑定关系:你在函数内给n赋值为5,修改的只是函数内部这份独立拷贝的值,完全不会影响外部作用域的b,所以最终打印b还是3。
let b = 3; function t(n) { n = 5; // 仅修改函数内部局部变量n,和外部b无关 } t(b) console.log(b) // 输出3
第二个示例能生效,本质是没有尝试在函数内部跨作用域修改外部变量,而是让函数把计算结果作为返回值抛出,在外部作用域主动拿返回值给b做重新赋值,自然能改变b的值:
let b = 3; function t() { return 5; } b = t(); // 外部作用域主动给b重新赋值为函数返回值 console.log(b) // 输出5
容易混淆的特殊情况
如果传入函数的是引用类型(对象、数组、函数等),你会发现修改对象的属性时外部能感知到变化,这不是因为JS变成了按引用传递,而是因为你拷贝到形参里的值是对象的堆内存地址:形参和外部变量存的是同一个地址,指向堆内存里的同一份对象,顺着地址修改对象属性时,外部访问同一个对象自然能看到变化。但如果你直接在函数内部给形参重新赋值为一个全新的对象,还是无法修改外部变量的指向。
// 引用类型传参示例 let obj = { value: 3 }; function modifyObj(param) { param.value = 5; // 顺着地址修改堆上的对象属性,外部可见 // param = { value: 10 }; 直接给形参重新赋值新对象,不会影响外部obj } modifyObj(obj); console.log(obj.value) // 输出5
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

