2、数据、内存和变量
2.1、什么是数据
存储在内存中代表特定的信息的东西,本质上是一串二进制组成的,如01110011…
数据的特点是:可传递(var a=2;var b=a;)、可运算(var c = a+b;)
万物皆数据,函数也是数据
内存中所有操作的目标:数据(如能进行算术、逻辑、赋值、运行函数…)
// 所有的内容都是数据,只要是数据就会占用内存。 var str = "abcdefg";// 分配内存给字符串。 var obj = {};// 分配内存给对象。 var arr = [1,2,3,4];// 分配内存给数组 var num = 1; var fn = function () { }
2.2、什么是内存
- 内存条通电后产生的可储存数据的空间(临时的)称为内存。
注:内存空间是临时的,而硬盘空间是持久的- 内存产生和死亡:内存条(电路版型)=>通电=>产生内存空间=>储存数据=>断电=>内存和数据消失
- 内存的分类
(1)栈 (stack) :全局变量/局部变量
(2)堆 (heap) :对象- 一块内存包含2个数据
- 内部存储的数据
- 内存地址值数据
- 总结:内存分为:栈 堆。栈和堆数据包含:地址,值
2.3、什么是变量
可变化的量,有变量名和变量值组成(例 var a=1);
每个变量都对应一块小内存,变量名用来查找对应的内存,变量的值就是内存中保存的数据
// 未使用变量 var sex = 1; if(sex === 1){ console.log("男") }else if (sex === 2){ console.log("女"); }else if(sex === 0){ console.log("未知") } // 使用变量 var sexEnum = { 0:"未知", 1:"男", 2:"女" } var sex = 0; console.log(sexEnum[sex]);
2.4、变量,数据,内存三者的关系
- 内存是用来存储数据的空间
- 变量是内存的标识,通过变量名可以找到这块内存,从而获取数据
2.5、思考1:a内存中保存的是什么
var
a=xxx
,a内存中保存的是什么?
当a的值是一个基本类型时,数据是放置在栈当中的。
var a = "abcdefg"; /* 1、将你的变量a作为标识符, 2、通过标识符去栈当中查找到内存,通过地址值 3、将内存当中地址值相对应的数据值进行获取。 */ console.log(a);// abcdefg
内存:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PAnsyZKO-1622806304943)(assets\1622447114439.png)]
当obj的值是一个引用类型时:值是保存在堆中的,在栈当中只是保留了一个地址(引用地址)
var obj = { userName:"laowang" } // 1、将obj作为一个标识符 // 2、通过标识符找到栈中的地址值 // 3、通过地址值可以找到对应的数据的值(引用地址值)。引用地址值是堆的地址值 // 4、通过引用地址值可以去堆中找到相对应的数据的值。该数据的值即是obj存储的值。 console.log(obj);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oMVFLm1V-1622806304944)(assets\1622447438735.png)]
当a的值是一个变量时:
- 将一个值为基本类型的变量
str
赋值给变量avar str = "my"; var a = str;// 是将栈当中的数据的值 console.log(a);// my;
内存:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4FgT7Gz4-1622806304945)(assets\1622449120790.png)]
将一个值为引用类型的变量obj赋值给变量a
var obj = {age:1}; var a = obj;// 是将栈当中的数据的值 console.log(a);// {age:1} a.age = 100; console.log(obj.age);// 100
内存:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gu12mtRh-1622806304946)(assets\1622449489593.png)]
2.6、思考2:引用变量赋值的问题
两个引用变的值(堆)一样的,那么比较结果 是否为true
- 注意:引用类型在比较时,传参时,赋值时,都是以栈当中存储 的数据值为依据的
var obj = { userName:"zhangsan" }; var obj2 = { userName:"zhangsan" }; console.log(obj === obj2);// false
内存:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oDHmjVTE-1622806304947)(assets\1622450076151.png)]
2个引用变量指向同一个对象, 通过一个引用变量修改对象内部数据, 另一个引用变量也看得见
var obj = { userName:"laowang", age:80 } var obj2 = obj; console.log(obj===obj2);// true obj2.age = 90; console.log(obj.age);// 90
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PSrQjIZh-1622806304947)(assets\1622450287299.png)]
2个引用变量指向同一个对象,让一个引用变量指向另一个对象, 另一个引用变量还是指向原来的对象
var obj = { userName:"laowang", age;80 } var obj2 = obj; obj = { userName:"laoli" } console.log(obj===obj2);// false
在
js
调用函数时传递变量参数时, 是值传递还是引用传递?// 栈当中的数据值(引用地址值) function run(a) { console.log(a === obj); a.userName = "laolitou"; } var obj = { userName:"laowang" } run(obj); console.log(obj.userName);// laolitou
2.7、思考3:JS
引擎如何管理内存?
内存生命周期
分配需要的内存
使用(存/取)分配到的内存
不需要时将其释放/归还
// 全局变量:不会主动释放。刷新页面会从内存移除。 var userName = "laowangtou";// 分配需要的内存 console.log(userName);// 去内存当中找到该值,然后输出。属于使用分配到的内存 userName = "xiaozhang";// 属于使用分配到的内存 // 局部变量 function run(){ var age = 12;// 分配需要的内存 age = 13;//属于使用分配到的内存 console.log(age);// 属于使用分配到的内存 // 该函数执行完比之后,通过垃圾回收机制将该age所占用的内存收回 } run();
释放内存
- 函数当中定义的变量,会在该函数运行完毕之后进行垃圾回收。(栈——》释放 ,堆:垃圾对象,回收)
- 存储对象的堆空间内存: 当内存没有引用指向时, 对象成为垃圾对象, 垃圾回收器后面就会回收释放此内存