从怀疑console.log为异步开始到深拷贝的实际应用...

441 阅读3分钟

A612317E75B65D4D95EDD2FB9D65B4FA.jpg

前言

转眼间实习过了快一个多月了,在杭州的一个多月的时间有收获也有成长,回想起当初在学校里一个人苦苦准备面试,写项目的时光,也是非常感慨。工作也并不比在学校的日子更轻松,最近时间有些充裕,那就将遇到的问题做一个总结吧!😎

9F22D771C925BA0D167B6D664E497701.jpg

console.log是异步输出吗?

在工作场景中,我们经常会用到console.log()进行打印输出对应的变量来纠察检测所写业务逻辑的纰漏,或者直接在代码语句中打上断点,即设置debugger,然后在控制台中进行变量值的检查。我们都知道console.log()是同步输出的模式,可是让人感到非常怪异的是,我却在打印变量的过程中得到了以下的结果...

cfa.png

是不是很神奇!?控制台的标题显示的是我传入的我所需的正确的值,可当我展开这个数组时,数据竟然发生了改变,而且循环打印出来的两个数据值竟是一样的。。。

%@D{CLSNXD%J@)02E3(3@ED.jpg

由于我所负责的项目很大,这个界面逻辑处理非常复杂,我反反复复地进行业务逻辑地检查,不停地打印输出,还是找不到,百思不得其解问题到底出在哪里?难道console.log是异步输出的吗?不应该啊😐于是,我经过查找相关资料,发现console.log确实是同步输出的,只是由于console.log()打印的值出现在控制台上的时候,显示的是改变的对象的引用值,当再次展开对象时,chrome就会重新在内存中查找对应的数据。

到这里其实问题就很清楚了,我做的for循环,每次在循环的时候看似是改变了数据的值,其实只是只是改变了数据的引用值,和基础数据不同,我所修改的数据类型是引用数据类型,要找到引用数据类型所对应的值,就要先在栈内存找到地址,然后根据这个地址在堆内存中找到需要的数据,而我一直循环只是在改变栈内存的值!

如何使用深拷贝?

发现了问题的痛点,那我该如何解决这个问题呢?这就涉及到了浅拷贝和深拷贝的应用了。曾经写过浅拷贝和深拷贝的区别,在这里就不赘述了,想了解的朋友可以点击本文下方的链接进行查找😀

在复制数据类型时,对于基础数据类型,如numberstringBoolean等,是不会有浅拷贝和深拷贝的考虑的,所以,当我们真正在谈论深浅拷贝时,需要处理的数据一定是对象、数组这种引用数据类型。

lok.png

这部分的代码比较复杂,简单解释下,思路就是设置一个替代的数据tempData,然后循环遍历给tempData进行赋值,一轮循环赋值完毕后,将tempData放入一个数组dataSource,然后在下边对tempData进行深拷贝,即引用值和内存值全部复制一遍,在堆内存中开辟一个新的内存空间。这样就能解决了console.log()打印值和展开值不一样的问题

也有一种说法是说console.log()的打印容易出问题,使用debugger会更好,不会有疑似异步的情况出现...😶。可是利用debugger打断点的方法我也试过,还是无法解决...

文章链接

juejin.cn/post/695124…

结尾

这个问题到此就解决了,后面打印包括赋值也是正确的,但是后续代码改动比较大,我找不到赋值成功的截图😥了,小伙伴们试试就好,当然这是我不成熟的想法,缺漏之处还望各位大佬们指点一下,欢迎交流,不胜感激!🥰

;pmm.gif