一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝
写在最前面:在javascript栏目下这是我即将开始写的一个系列,主要是在框架横行的时代,虽然上班用的是框架,但是对于面试,以及技术进阶,JS基础知识的铺垫是锦上添花,也是不得不学习的一块知识,虽然开汽车的不需要很懂汽车,只需要掌握汽车的常用功能即可。但是如果你懂汽车,那你也能更好地开车,同理。当然,一篇文章也不会光光只讲一个知识点,一般会将有关联的知识点串联起来,一边记录自己的学习,一边分享自己的学习,互勉!如果可以的话,也请给我点个赞,你的点赞也能让我更加努力地更新!
概览
- 食用时间: 6-12分钟
- 难度: 简单,别跑,看完再走
JS内存生命周期
分配内存
内存的读与写
释放内存
栈内存与堆内存
JS数据类型
在讲栈内存与堆内存之前,大家应该都知道JS分为两种数据类型:
-
基本数据类型
String , Number , Boolean , null , undefined , Symbol (大小固定,体积轻量,相对简单)
-
引用数据类型
Object , Array , Function (大小不一定,占用空间较大,相对复杂)
内存存储机制
var a=true; //布尔型,基本数据类型var b='jack'; //字符型,基本数据类型var c=18; //数值型,基本数据类型var d={name:'jack'}; //对象,引用数据类型var d=[0,1,2,3,4,5]; //数组,引用数据类型复制代码
正是因为数据类型的不同,所以他们的存放方式也不同,就和现实生活中穷人和富人的住所完全不一样(扯远了)。我们先来看一张图:

可以看到, a
, b
, c
都是基本数据类型, d
和 e
都是引用数据类型,他们在存放方式上有着本质性的区别,基本数据类型的值是存放在栈内存中的,而引用数据类型的值是存放在堆内存中的,栈内存中仅仅存放着它在栈内存中的引用(即它在堆内存中的地址),就和它的名字一样,引用数据类型
内存访问机制
上面讲的是存储,接下来说一下变量的访问,基本数据类型可以直接从栈内存中访问变量的值,而引用数据类型要先从栈内存中找到它对应的引用地址,再拿着这个引用地址,去堆内存中查找,才能拿到变量的值
深浅拷贝
浅拷贝
上面已经和大家说过了基本数据类型与引用数据类型在存储上的不同,那么,接下来说的这个深浅拷贝,想必大家也在面试题中经常碰到,老方式,先来看一段代码
var name='jack';var obj={ age:24};var nameCopy=name;var objCopy=obj; nameCopy='bob'; objCopy.age=15;console.log(name); //jackconsole.log(obj.age); //15复制代码
登录后复制你会发现,
name
是没有被影响的,而我们命名是修改objCopy.age
,为什么还会影响到obj.age
呢,这就是因为深浅拷贝的问题在捣鬼,先来看下下面的一张图

之所以会出现这种情况,是因为JS对于基本类型和引用类型的,当我们在复制引用类型的时候,复制的是该对象的引用地址,所以,在执行 var objCopy=obj;
的时候,将 obj
的引用地址复制给了 objCopy
,所以,这两个对象实际指向的是同一个对象,即改变 objCopy
的同时也改变了 obj
的值,我们将这种情况称为浅拷贝,仅仅复制了对象的引用,并没有开辟新的内存,拿人手短,拷贝地太浅了。(只有引用类型才会出现浅拷贝的情况)
深拷贝
再来看接下来的一段代码
var name='jack';var obj={ age:24};var nameCopy=name;var objCopy=JSON.parse(JSON.stringify(obj)); nameCopy='bob'; objCopy.age=15;console.log(name); //jackconsole.log(obj.age); //24复制代码
登录后复制可以发现,在经过
JSON.parse(JSON.stringify(obj))
转换了以后,浅拷贝不复存在,这一波是深拷贝,深拷贝开辟了新的堆内存地址,并且将对象的引用指向了新开辟的内存地址,和前面复制的对象完全独立,自立根生,拷贝地很深,学功夫学到家,自立门户的感觉。另外实现深拷贝的方法(更多方式请自行百度)
var objCopy=Object.assign({},obj); //对象深拷贝的方法 Object.assign var arrayCopy=array.concat(); //数组深拷贝的方法 concat() (数组无嵌套对象或者数组可用) var arrayCopy=array.slice(); //数组深拷贝的方法 slice() (数组无嵌套对象或者数组可用) JSON.parse(JSON.stringify(array)) //顺带提下,JSON.parse(JSON.stringify()) 数组和对象通用复制代码
登录后复制接着上面的数组容易踩坑的地方 ,来看一个例子
var array = [{name: 'jack'}, ['old']];var arrCopy = array.concat(); arrCopy[0].name='new';console.log(array); // [{name: 'new'}, ['old']]console.log(arrCopy); // [{name: 'new'}, ['old']]复制代码
登录后复制可以清楚地看到(数组无嵌套对象或者数组可用的情况下用
concat
和slice
才有效)系列目录
一张纸搞懂JS系列(1)之编译原理,作用域,作用域链,变量提升,暂时性死区
一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝
一张纸搞懂JS系列(3)之垃圾回收机制,内存泄漏,闭包
更多相关免费学习推荐:javascript(视频)
以上是一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

探索前端中类似VSCode的面板拖拽调整功能的实现在前端开发中,如何实现类似于VSCode...
