1.什么是数据
数据是存储在内存中代表特定信息的东西,本质上是010101…
数据的特点:可传递,可运算
一切皆数据
内存中所有操作的目标:数据
- 算术运算
- 逻辑运算
- 赋值
- 运行函数
注意
:数据可以执行什么操作要看数据的类型
2.什么是内存
内存条通电后产生的可存储数据的空间(临时的)
内存产生和死亡:内存条(电路板)–> 通电 --> 产生内存空间–> 存储数据–> 处理数据–> 断电–> 内存空间和数据都消失
一块小内存有两个数据:
- 内部存储的数据
- 地址值
内存的分类
- 栈 全局变量跟局部变量
- 堆 对象
标识对象的变量是在栈空间中的
3.什么是变量
- 变量存在栈空间中,没有数据,给变量赋值其实就是将值在内存中的地址传给变量
- 可变化的量,由变量名和变量值组成
- 每个变量都对应一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的数据
4.内存、数据、变量三者之间的关系
- 内存是用来存储数据的空间
- 变量是内存的标识
内存、数据、变量的关系图
相关例子
<script>
var age = 18
console.log(age);
const obj = {
name: 'Tom'
};
/*
以上对象赋值的过程其实是将{name: 'Tom'}的地址值保存到obj这个变量中,
调用该变量时,其实是去找它的内存
*/
var a = obj; // 其实这里是将变量obj中存的内容(地址值)拷贝一份传给a
console.log(a);
a.age = 18;
console.log(a); // {name: 'Tom', age: 18}
console.log(obj); // {name: 'Tom', age: 18}
/*
这里就可以很明显的看到,a 和 obj其实指向的都是同一个地址,
当改变了变量a的内容的时候其实就是改变obj跟a所指向的那块内容,
所以输出obj时,它的结果跟a是一样的
*/
console.log(obj.name); // Tom
/*
以上obj.name的执行过程:
先获取obj中的内容,然后再去访问obj这个地址所指向的内容,然后再通过点运算符访问内容
- 注意只有变量的内存存的是地址才能点
找任何数据都是根据名称找到对应的内存,再读取它内存里面的值
只有对象才是读地址值,其他都是直接读内容的
*/
</script>
5.相关问题
(1)关于赋值和内存的问题
问题
:var a = xxx
,a内存中保存的到底是什么?
- 1.xxx是基本数据,保存的就是这个数据
- 2.xxx是对象,保存的就是对象的地址
- 3.xxx是一个变量,保存的是xxx的内存内容(可能是基本数据,也可能是地址值)
(2)关于引用变量赋值问题
n个引用变量指向同一个对象,通过一个变量修改对象内部数据,另一个变量看到的是修改之后的数据
如:
var obj1 = {name: 'Tom'}
var obj2 = obj1
obj2.age = 12
console.log(obj1.age) // 12
function fn(obj) {
obj.name = 'Bob';
}
fn(obj1)
console.log(obj2.name); // Bob
2个变量指向同一个对象,让其中一个引用变量指向另一个对象,另一个引用变量依然指向前一个对象
如:
var a = {age: 12}
var b = a
a = {name: '小明', age: 13}
console.log(b.age, a.name, a.age) // 12 小明 13
function fn2 (obj) {
obj = {age: 15}
/*
这里其实是改变了变量中存储的地址值,并不仅仅只是改变之前那个对象的age
但是要注意的是,这里的赋值操作是局部变量的赋值操作
也就是说传进来的参数(变量)只在当前函数体内有用,离开函数体后无效,之前指向的是什么还是什么
*/
}
fn2(a)
console.log(a.age) // 13
console.log(a) // {name: '小明', age: 13}
(3)关于数据传递问题
问题
:在js调用函数传递变量参数时,是值传递还是引用传递?
- 理解1:都是值(基本/地址值)传递
- 理解2:可能是值传递,也可能是引用传递(地址值)
相关例子
var a = 3
function fn () {
a = a + 1
}
fn(a)
console.log(a) // 3
function fn2 (obj) {
console.log(obj.name)
}
var obj = {name: '小明'}
fn2(obj)
(4)js引擎如何管理内存
a.内存生命周期
- 分配小内存空间,得到它的使用权
- 存储数据,可以反复进行操作
- 释放小内存空间
b.释放内存
- 局部变量:函数执行完自动释放
- 对象:成为垃圾对象–>垃圾回收器回收
- 全局变量:不会被释放,可以赋值null使其成为垃圾对象
function fn() {
var b = {}
}
fn() // b是自动释放,b所指向的对象是后面某个时刻由垃圾回收器回收