你还在傻傻的认为传递分为值传递和引用传递吗?

前言

这篇文章是本人在读红宝书(第四版)4.1.3节-传递参数时引发的思考产出的最终结果,记录一下思考的过程。因为函数传参的过程其实就是变量赋值的过程,所以本文全部用变量赋值举例。若各位大佬有不同见解,欢迎探讨!

先说结论:在传递操作中只有值传递,没有引用传递。

我们大多都是把这两个概念混淆在一起,所以会觉得存在引用传递,接下来我们先区分传递和访问两种概念。

值传递是指在变量赋值的过程,并且会将原变量的值复制一份出来赋给新变量,两个变量互不相干。

ini 复制代码
const a = 1;  // 这是一次值传递操作
let b = a; // 这也是一次值传递操作
b = 2;
console.log(a); // 1  修改b的值不会影响a

访问是指读取变量值的过程,分为按值访问、按引用访问

按值访问

其实值传递的过程中会涉及到访问的操作,比如我有一个变量a值为1,现在要将a的值赋值给一个新的变量b,首先得拿到a的值才能赋值给b,在访问a的具体值的过程所使用的访问方式就是按值访问。

ini 复制代码
const a = 1;  
let b = a; // 这里需要先拿到a的值,才能赋值给b
按引用访问

按引用访问概念和按值访问差不多,我们都知道像对象、数组等等一些复杂的数据类型是存储在堆内存中的。所以我们的变量中存的是存在堆内存中数据的地址,访问该变量时会根据变量对应的内存地址去堆内存中查找对应的数据,这个访问方式称为按引用访问。

ini 复制代码
const obj = {
    a: 1
};  
const obj1 = obj; // 这里需要先拿到obj的值,也就是该对象在堆内存中的地址,才能赋值给obj1

可以看到我们在将obj的对象赋值给obj1时,实质上是复制了一份地址给obj1,因此我们可以通过更改变量的地址来使其脱离原来对象的引用。

ini 复制代码
const obj = {
  a: 1,
  b: 2,
};
let obj1 = obj;
obj1.a = "a";
console.log(obj); // { a: 'a', b: 2 }
obj1 = {}
obj1.a = "a1"
console.log(obj); // { a: 'a', b: 2 }
console.log(obj1);  // { a: 'a1' }

上述代码第一个打印结果证明obj1和obj操作的是同一个对象,因为他们所对应的是同一个堆对象地址,地址相同,所以对象相同。

接下来将obj1赋值为空对象,我们可以先理一下这一步会发生什么。首先有一个空对象,就会在堆内存中开辟一个新的空间来存储这个空对象,然后将这个新空间的地址赋值给obj1。此时obj1和obj对应的对象内存地址已经不一致了,所以接下来对obj1对象的操作不会再影响obj的对象。

所以我们通过给obj1赋值新对象的方式,使其与obj的对象脱离绑定,互不影响,这不就是值传递的概念么。

结论:只有值传递,没有引用传递!

相关推荐
zhangyao9403309 小时前
开发pc端时,表格的高度怎么设置才能铺满页面
前端·javascript·elementui
XinZong9 小时前
实测OpenClaw虾淘:全民工具AI时代,冷门非工具类的Skill还能出圈吗?
javascript
烛衔溟10 小时前
TypeScript 类的类型 —— 作为类型使用
javascript·ubuntu·typescript
之歆10 小时前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化
kyriewen10 小时前
我关掉了Copilot:因为我写的代码出现在了别人的建议里
前端·javascript·ai编程
SmartRadio11 小时前
STM32WLE5 LoRa Smart TDMA 完整协议栈实现(工程级可直接编译)-【1】
javascript·stm32·单片机·嵌入式硬件·lora·自组网·smart tdma
竹林81811 小时前
用 wagmi v2 踩坑两天,我终于搞懂了多链钱包切换
前端·javascript
子云zy12 小时前
JS 对象与包装类:new 做了什么?字符串为什么有 length?
前端·javascript
茶底世界之下13 小时前
你的 Mac 里,藏着一支 AI 开发团队
前端·javascript
小白学大数据13 小时前
Playwright 爬虫:Python 爬取 JS 渲染的 JSP 网站
开发语言·javascript·爬虫·python·数据分析