-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
【进阶1-3期】JavaScript深入之内存空间详细图解 #14
Comments
a.x = a = {n: 2}; |
理解了。 a.x 是已经先指向原对象了。 然后在赋值。 |
a.x = a = {n:2} 执行顺序 a.x -> a = {n:2} -> (a.x)= a (.运算符优先级大于=) |
从右往左 |
最后a={n:2},b={n=1,x:{n:2}} |
点运算优先级最高 |
关键点在于对象的引用和点运算符的优先级 |
a.x = undefined |
个人理解:取属性的运算符优先级最高,赋值运算符是右结合性的。 |
转一篇针对思考题的文章 |
a.x = {n: 2}; |
原文 - “将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。” |
https://www.zhihu.com/question/41220520 看了这个你还不懂的话,你来找我 |
先执行‘.’,于是a.x = a = {n: 2}可以理解成({ n: 1 }).x = a = { n:2 } |
循环调用栈溢出,我的浏览器报错是 |
这个网站可以查看执行过程
|
.优先级大于赋值 a.x先声明 随后赋值右到左 a={n:2}返回{n:2}此时内存中b.x指向{n:2} |
没必要在这里提堆数据结构,堆栈的堆和数据结构的堆是两回事 |
原文中:基本类型 --> 保存在栈内存中。callstack frame 一旦 pop up 掉,请问闭包去哪里找数据? |
本期的主题是调用堆栈,本计划一共28期,每期重点攻克一个面试重难点,如果你还不了解本进阶计划,文末点击查看全部文章。
如果觉得本系列不错,欢迎点赞、评论、转发,您的支持就是我坚持的最大动力。
堆栈的内容和执行顺序我就不说了,前面两篇已经介绍过了。
但是今天补充一个知识点:某些情况下,调用堆栈中函数调用的数量超出了调用堆栈的实际大小,浏览器会抛出一个错误终止运行。
对于下面的递归就会无限制的执行下去,直到超出调用堆栈的实际大小,这个是浏览器定义的。
现在正式开始今天的主题,内存空间详解
栈数据结构
栈的结构就是后进先出**(LIFO)**,如果读过前面两篇文章应该是相当熟悉了。文中使用乒乓球盒子的结构来解释。
处于盒子中最顶层的乒乓球5,它一定是最后被放进去,但可以最先被使用。而我们想要使用底层的乒乓球1,就必须将上面的4个乒乓球取出来,让乒乓球1处于盒子顶层。
堆数据结构
堆数据结构是一种树状结构。它的存取数据的方式与书架和书非常相似。我们只需要知道书的名字就可以直接取出书了,并不需要把上面的书取出来。JSON格式的数据中,我们存储的
key-value
可以是无序的,因为顺序的不同并不影响我们的使用,我们只需要关心书的名字。队列
队列是一种先进先出(FIFO)的数据结构,这是事件循环(Event Loop)的基础结构,事件循环我们会在第8期详解介绍。
变量的存放
首先我们应该知道内存中有栈和堆,那么变量应该存放在哪里呢,堆?栈?
在计算机的数据结构中,栈比堆的运算速度快,Object是一个复杂的结构且可以扩展:数组可扩充,对象可添加属性,都可以增删改查。将他们放在堆中是为了不影响栈的效率。而是通过引用的方式查找到堆中的实际对象再进行操作。所以查找引用类型值的时候先去栈查找再去堆查找。
几个问题
问题1:
问题2:
问题3:
现在来解答一下,三个问题的答案分别是
20
、‘进阶’
、{ name: '前端开发' }
b.name
的值后,相应的a.name
也就发生了改变。null
是基本类型,a = null
之后只是把a存储在栈内存中地址改变成了基本类型null,并不会影响堆内存中的对象,所以b的值不受影响。内存空间管理
JavaScript的内存生命周期是
JavaScript有自动垃圾收集机制,最常用的是通过标记清除的算法来找到哪些对象是不再继续使用的,使用
a = null
其实仅仅只是做了一个释放引用的操作,让 a 原本对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。在局部作用域中,当函数执行完毕,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收。但是全局变量什么时候需要自动释放内存空间则很难判断,因此在开发中,需要尽量避免使用全局变量。
思考题
参考
进阶系列目录
交流
进阶系列文章汇总:https://github.com/yygmind/blog,内有优质前端资料,觉得不错点个star。
我是木易杨,网易高级前端工程师,跟着我每周重点攻克一个前端面试重难点。接下来让我带你走进高级前端的世界,在进阶的路上,共勉!
The text was updated successfully, but these errors were encountered: