理解JS中按值传递及按引用传递

华为怎么进BT365 admin 2025-08-26 14:46:08

在程序语言中,变量的赋值以及相互之间的引用绝对是使用最频繁的。但在这种引用的过程中很容易出现一个问题:比如为变量a赋了某个值,变量b引用了变量a,此后我们修改了b的内容,却发现有时a的值也变了,有的时候却不变,这是为什么?

引用指向的是值JavaScript中变量的引用指向的是值,即使一个值被多个变量引用,他们所指向的都是同一个值,彼此并无关联。影响引用传递结果的是值的类型。

基本类型与引用类型JavaScript值有两大类型:基本类型与引用类型。基本类型包括数字、字符串、布尔、null、undefined和ES6中的symbol。引用类型包括对象(数组和内置对象)和函数。基本类型值是简单的数据段,直接保存在内存中。引用类型值是对象,可以添加、修改和删除属性或方法,但无法直接访问,需要通过内存地址访问。

当为变量引用基本类型的值时,实际上会拷贝一个值副本给新的变量,引用相同基本类型值的变量相互独立,如下图:

代码验证:

123456// 例一let num1 = 5let num2 = num1num2 ++console.log(num2) // 6console.log(num1) // 5

可以看到虽然num2引用了num1的值,但是仅仅是拷贝了相同的值,num2的变化不会传递给num1。

而当为变量赋予引用类型的值时,拷贝的是内存地址,不同的变量指向的是同一个对象。因此当变量修改了某些属性时会改变其内存地址指向的对象:

1234567891011121314// 例二let person = { name: 'Jackson'}let man = personman.name = 'blackstar'console.log(person.name) // blackstar// 例三let arr1 = [1,2,3]let arr2 = arr1arr2.push(4)console.log(arr2) // [1,2,3,4]console.log(arr1) // [1,2,3,4]

修改变量会改变内存地址指向的对象,由此会影响所有引用同一地址的变量。但前提是修改对象属性,而不是重新赋值新的引用类型值:

12345678910111213141516// 例四let person = { name: 'Jackson'}let man = personman = { name: 'blackstar'}console.log(person.name) // Jackson// 例五let arr1 = [1,2,3]let arr2 = arr1arr2 = [4,5,6]console.log(arr2) // [4,5,6]console.log(arr1) // [1,2,3]

重新赋值改变了内存地址,指向了一个新的对象,从原本共同引用的对象中脱离开来,自立门户,自然也就不会影响其他变量了。

再来一个组合代码强化一下理解:

123456789101112131415161718// 例六const obj = { info: { age: 26 }}let fe = obj.infolet age = obj.info.ageobj.info.age = 16console.log(fe) // { age: 16 } 引用的对象属性发生变化,变量跟随改变console.log(age) // 26 变量拷贝的是基本类型值,不会受对象改变影响fe.age = 41console.log(obj.info) // { age: 41 } 属性修改,相互影响fe = { name: 'blackstar'};console.log(fe); // { name: 'blackstar' }console.log(obj.info); // { age: 41 } 变量指向了新的对象,不影响原来引用的对象

函数参数是按值传递?No!不能这么说,还是和开头我们所说的一样,如何传递仍然取决于值的类型,基本类型按值传递,引用类型按引用传递。

1234567891011121314151617// 例七function foo(wrapper) { wrapper.a = 42}let obj = { a: 2}foo(obj)console.log(obj.a) // 42// 例八function count(value) { value += 10}let num = 10count(num)console.log(num) // 10

你看,我们将一个引用了对象的变量传入函数并且在函数中改变对象的属性,函数外该变量也会同步发生改变,若传入一个基本类型值则不然,这和我们之前实验的结果一致。

总结由于引用类型赋值操作保存的是指向对象的内存地址,指向的是同一对象,因此很容易在传递的过程中相互影响,理解不同类型值的传递规则,明确拷贝的目的是拷贝值副本还是建立联系,这会使数据的流转更加分明和清晰。

相关文章

夕张总览

【干货】电影行业产业链全景梳理及区域热力地图

支付寶螞蟻森林種樹多久能收獲果實?詳解種樹規則與收益

诗词·散曲《李凭箜篌引》原文与翻译、赏析

世界杯期间,为何愿意排队去买足球彩票?彩票店有多赚钱?

铁手的武功出自哪个流派(铁手)

女足世界杯今晚对战 激烈对决,预测胜负

《王者荣耀》装备噬神之书详解

过年期间干什么兼职比较挣钱?试试这几种兼职!