> For the complete documentation index, see [llms.txt](https://sekin.gitbook.io/myjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sekin.gitbook.io/myjs/nei-cun-de-na-xie-shi/zhan-nei-cun-he-dui-nei-cun.md).

# 栈内存和堆内存

JavaScript 是如何工作的：引擎，运行时和调用堆栈的概述 ：参考地址<http://tcatche.site/2017/08/how-javascript-work-part-1-overview/>

stack和heap在内存里的是怎么的具体讲解 ： <http://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html>

***数据类型：null , underfind , string, number , boolean , object .。数据类型和内存的关系：（详细讲解在腾讯课堂《**\_Web前端开发之JavaScript精英课堂【渡一教育】***》第一章第2节——***js介绍,入门,js引入,变量,值类型,运算符，第50分钟开始***）**\_

| 栈内存 stack | 栈内存  | 栈内存   |   | 堆内存heap      |
| --------- | ---- | ----- | - | ------------ |
| 变量        | 地址   | 值     |   | 引用           |
| a         | A001 | "字符串" |   |              |
| b         | A002 | A002  |   | \[1,2,3,4,5] |
|           |      |       |   |              |
|           |      |       |   |              |

如上图，申明两个变量，一个是原始类型a(string)，一个是引用类型b(array)。

> 当 var a = 1，b = \[1,2,3,4,5]其实是做了两件事，声明一个内存空间，然后放一个值。a是原始类型，栈内存里保存的是他的值，但是b是引用类型，栈内存保存的是他的一个地址，这个地址指向堆内存里保存的那个数组。
>
> var c = b ;
>
> c.push(5);
>
> 此时把b复制给c ,是把b在栈内存里保存的东西复制给了c,即复制的是一个指向堆内存的地址。所以当我们直接操作c 的时候，操作的是堆内存的数组，因为b也是指向这个数组的，所以b的值也在一同改变。
>
> c =\["我还是我"，“你还是你？”]；
>
> 当我再给c 赋值的时候，b会有变化吗？
>
> 不管是引用类型还是原始类型，当我们给定初始值或重新赋值的时候，都没有删除或是覆盖内存里的任何一块位置内存。拿手机里的内存来说，当手机提示我们内存不够的时候，删除一个视频，删除的只是这个视频的地址和他对应的内存的关系，删除后就再也不能通过这个地址在内存里找到他保存的位置，然而这个视频还是存在的。这就是为什么在电脑里删除了一些东西，就是在回收站里也删除了，去一些特别维修店也可以找回来。\*\*
>
> 那重新赋值是什么操作？
>
> a = "5" // 重新给a 赋值
>
> 这个操作其实又是在栈内存重新分配了一个空间即内存，保存这个原始类型的值，要是引用类型即保存的是地址，且重新再堆内存分配了一个空间保存值即引用类型，把之前的变量和内存的关系解除，重新给新赋值的。
>
> 进一步来说比如 c= 5, 再给a 赋值的时候，a=c,跟a = 5 ,是两种概念了。一个是变量，一个是数据。而且一个是复制，一个是赋值。
