一个 js 中值传递和引用传递的坑。

UFO研究
• 阅读 2690

今天在调试代码时遇到一个问题,刚开始想不明白,然后分析了一下后,才知道其中的问题,这也是一个基础的问题,(所以基础是很重要的)

代码如下:

var a = 3;
a = a * 2;
console.log(a); // a = 6

var b = 1, c =2, d = 3;
var arr1 = [b,c,d];
arr1.forEach((item)=>{
    item = item * 2;
});
console.log(arr1); //arr1 = [1,2,3];

var arr2 = [{a:1},{a:2},{a:3}];
arr2.forEach((item)=>{
    item.a = item.a*2;
});
console.log(arr2); //arr2 = [{a:2},{a:4},{a:6}]

如果你能不假思索的得出上面的答案,我相信你对这方面的知识已经很了解了,所以可以不用继续往下看了,如果你像我今天该开始一样,觉得有点疑惑的话,那么这篇文文章就很适合你。

  1. 首先我们应该知道的是,在 javascript 中,基本数据类型是通过值传递的。

比如:

var a=1,b;
    b = a;// 这时 a 和 b 的值都为 1
    a = 2;//这时 a 的值 为 2,b 的值还是为 1 ,

一个 js 中值传递和引用传递的坑。

所以当 b = a, a = 2;a直接赋给b的值 是1,所以 b 就等于 1,而 a 的变化改变不了 b 的值

  1. 在 js 中复杂数据类型是通过 引用传递的

比如:

var v1 = { a:1 };
var v2 = v1; //v2 = { a:1 }
v1.a = 2;
console.log(v2.a); // v2.a = 2;

一个 js 中值传递和引用传递的坑。

了解了以上的一些基础知识后,就不难理解最开始的代码输出结果了。

1.
    var a = 3;
    a = a * 2;
    console.log(a); // a = 6
    
2. 
    var b = 1, c =2, d = 3;
    var arr1 = [b,c,d];
    arr1.forEach((item)=>{
    item = item * 2;
    });
    console.log(arr1); //arr1 = [1,2,3];
    
3. 
    var arr2 = [{a:1},{a:2},{a:3}];
    arr2.forEach((item)=>{
    item.a = item.a*2;
    });
    console.log(arr2); //arr2 = [{a:2},{a:4},{a:6}]
    

第一段代码当然好理解,就是简单的值传递而已,然而第二段代码呢?我刚开始有点困惑的是,既然也是值传递,那为什么它的值没有变化还是原先的值,注意:这里我忽略了重要的一点,所以导致我不明白,那就是在这个 forEach 的遍历中,还存在一个赋值的过程,就是这个过程导致 arr1 的值没有改变,在每次循环中 arr1中的值都会赋给 item, 就是 item = b, item = c,item = d,所以后面对item 的改变就与 b,v,d 没有关系了。
所以那么 第三段也就很好理解了,他也与第二段代码一样,每次回存在一个赋值,但是注意的是 arr2 中存储的是对象,就是 item = { a:1 } ...,这样 item 仍然指向 arr2 中对象,所以这时对 item 的修改就可以通过 arr2 来反应出来。

虽然这只是自己的粗心造成的,但仍然是自己的基础不扎实而导致的,所以想要成为好的程序员,基础是非常重要的。希望大家都能注重基础的知识,为自己学习高级东西而打下坚实的基础。

点赞
收藏
评论区
推荐文章
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
阿邹 阿邹
4年前
java传值和传引用问题
这个问题还是很常见的,如果你平常敲代码比较多你可能经常会遇到这个问题。如果你知道java这个机制,你可能还会一直在找代码的问题。java中的值传递和引用传递。比如下面有这俩个方法javaprivatevoidupdataValue(Strings){s"123";}privatevoidupd
Wesley13 Wesley13
3年前
Java里的按值传递与引用传递
按值传递还是按引用传递这个在Java里面是经常被提起的问题,也有一些争论,似乎最后还有一个所谓的结论:“在Java里面参数传递都是按值传递”。事实上,这很容易让人迷惑,下面先分别看看什么是按值传递,什么是按引用传递,只要能正确理解,至于称作按什么传递就不是个大问题了。1:按值传递是什么指的是在方法调用时,传递的参
可莉 可莉
3年前
15张图带你彻底明白spring循环依赖,再也不用怕了
1.由同事抛的一个问题开始最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到。平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的几个问题后,重新刷新了我的认识。我们先看看当时出问题的代码片段:@ServicepublicclassTestServic
Stella981 Stella981
3年前
Memory Analyzer Tool定位Java heap space内存泄漏
javaheapspace是一个很蛋疼的问题,如果开发调试时遇到还好,如果是在项目上线后运行一段时间后,才抛出该异常,那真的很悲剧(那你得找代码中到底是哪里内存泄露了),这真是一个悲伤的故事。  1.javaheadspace堆内存溢出分 析发生这种问题的原因是java虚拟机创建的对象太多,
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Stella981 Stella981
3年前
Hibernate纯sql查询结果和该sql在数据库直接查询结果不一致
问题:今天在做一个查询的时候发现一个问题,我先在数据库实现了我需要的sql,然后我在代码中代码:selectdistinctd.id,d.name,COALESCE(c.count_num,0),COALESCE(c.count_fix,0),COALESCE(c
Stella981 Stella981
3年前
PowerDesigner列名、注释内容互换
在用PowerDesigner时,常常在NAME或Comment中写中文在Code中写英文,Name只会显示给我们看,Code会使用在代码中,但Comment中的文字会保存到数据库TABLE的Description中,有时候我们写好了Name再写一次Comment很麻烦,以下两段代码就可以解决这个问题。在PowerDesigner中PowerDesig
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Python进阶者 Python进阶者
1年前
盘点一个Python基础的问题
大家好,我是Python进阶者。一、前言前几天在Python最强王者交流群【金光灿灿】问了一个Python基础的问题。问题如下:请问为什么我下面的代码,无论输入什么都是输出else里面的内容啊?kushuju"小明":"1","小红":"2","小方":"
程序员一鸣 程序员一鸣
1个月前
鸿蒙开发:熟知@BuilderParam装饰器
所以在有@BuilderParam传递UI视图时,一定要注意this的指向问题,这也是为什么很多同学遇到在@Builder修饰的函数中为什么不刷新数据的问题,其原因就是this指向不对。
UFO研究
UFO研究
Lv1
我有故人抱剑去,斩尽春风未肯归。
文章
2
粉丝
0
获赞
0