一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
内存
内存就是暂时存储程序以及数据的地方,相对于外存而言(硬盘是外存的一种),我们在电脑上输入文字,字符的时候,它就会被存入内存中,只有当你选择保存文件的时候,内存中的数据才会被存入硬盘。
内存是CPU能够直接寻址的存储空间,存取速度快,临时存放数据,不能永久保存数据。
什么是内存地址
计算机把所有信息数字化了,所以它知道自己把一个数据,一条命令记到了内存中的哪些位置,例如下图中,“丁”和“A”的地址都是1000H。
一个内存地址=一个内存单元=一个字节(byte)1byte=8bit ;1字节=8位
内存大小:32位/64位操作系统就是和CPU的位数有关,CPU的位数是指CPU一次性可以处理数据或指令的能力。
引用
引用是一个变量的别名,为什么要引入别名?是因为我们想定义一个变量B,由这个变量B来共享变量A的内存空间,所以使用别名是一个好的选择。
变量A是一个内存空间的名字,如果我们给这个内存空间再另外起一个名字(变量B),就是能共享这个内存了,引用(别名)由此而来。
比如:
var obj = {a:1,b:2};
var obj1=obj;
以上我们就可以说变量obj1是变量obj的一个引用。
指针
指针,指向另一个内存空间的变量,我们可以用个指针来索引另一个内存空间中的内容。而指针本身有自己的内存空间。
堆,栈和队列
三者都属于数据结构。
1.栈(先进后出,后进先出)
2.基本数据结构的存储(存储栈)
js中,数据类型分为基本数据类型和引用数据类型,基本数据类型有:string、number、boolean、undefined、null、symbol、bigint。在内存中基本数据类型存储在栈中,按值访问。原型类型都存储在栈内存中,是大小固定并且有序的。
3.执行栈(函数调用栈)
接下来看看js中如何通过栈来管理多个执行上下文。
- 程序执行进入一个执行环境时,它的执行上下文就会被创建,并被推入执行栈中(入栈)。
- 程序执行完成时,它的执行上下文就会被销毁,并从栈顶被推出(出栈),控制权交由下一个执行上下文。
js中每一个可执行代码,在解释执行前,都会创建一个可执行上下文。按照可执行代码块可分为三种可执行上下文。
- 全局可执行上下文:每一个程序都有一个全局可执行代码,并且只有一个。任何不在函数内部的代码都在全局执行上下文。当JavaScript执行全局代码的时候,会编译全局代码并创建全局执行上下文,而且在整个页面的生存周期内,全局执行上下文只有一份。
- 函数可执行上下文:每当一个函数被调用时,都会为该函数创建一个新的上下文。每个函数都被调用时都会创建它自己的执行上下文。当调用一个函数的时候,函数体内的代码会被编译,并创建函数执行上下文,一般情况下,函数执行结束之后,创建的函数执行上下文会被销毁。
- Eval可执行上下文:Eval也有自己执行上下文。
因为JS执行中最先进入全局环境,所以处于“栈底的永远是全局环境的执行上下文”。而处于“栈顶的是当前正在执行函数的执行上下文”,当函数调用完成后,这个栈顶的就会被推出(理想情况下,闭包会组织该操作)。
全局环境只有一个,对应的全局执行上下文也只有一个,只有当页面被关闭之后它才会从执行栈中被推出,否则一直处于栈底。
let name = '蜗牛';
function sayName(name) {
sayNameStart(name);
}
function sayNameStart(name) {
sayNameEnd(name);
}
function sayNameEnd(name) {
console.log(name);
}
1.当代码进行时声明:内存堆
name='蜗牛'
sayName = fn;
sayNameStart = fn;
sayNameEnd = fn;
2.执行sayName函数时,会把直接函数压入执行栈,并且会创建执行上下文,执行完毕编译器会自动释放;
4.栈溢出问题
不同浏览器对调用栈的大小有限制,超出限制会出现栈溢出的问题