变量
- 基本类型值:简单数据段
- 引用类型值:可能由多个值构成的对象
JavaScript不允许直接访问内存中的位置,不能直接操作对象的内存空间。
属性
只能给引用类型值动态地添加属性。
复制
基本类型值:会在变量对象上创建一个新值
引用类型值:本质上都是指针,两个指针引用同一个对象
传递参数
所有函数的参数都是按值传递的。
1 | function setName(obj){ |
检测类型
- typeof:检测基本类型
- instanceof:检测引用类型,根据它的原型链来识别
- Object.prototype.toString()
执行环境及作用域
每个函数都有自己的执行环境,当执行流进入一个函数时,该函数的环境就会推入一个环境栈中。
当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的所有变量和函数的有序访问)。
全局执行环境的变量对象始终都是作用域链的最后一个对象。
标识符解析就是沿着作用域链一级一级地搜索标识符的过程,搜索过程始终从作用域链的前端开始,然后逐级向后回溯,直到找到标识符为止。
内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。
延长作用域链
- try-catch中的catch
- with
没有块级作用域(var)
- 在函数内部,最接近的环境就是函数的局部环境
- 查询标识符:搜索过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符
垃圾收集
标记清除:垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,接着会去掉环境中的变量以及被环境中变量引用的变量的标记。最后,垃圾收集器完成内存清除工作,销毁带有标记的值并回收所占用的内存空间
引用计数:跟踪记录每个值被引用的次数,当这个值为0,则回收
问题:循环引用,对象A包含对象B的指针,对象B包含对象A的指针
1
2
3
4
5
6function problem(){
const objA = new Object();
consy objB = new Object();
objA.some = objB;
objB.any = objA;
}
管理内存
解除引用:一旦数据不再使用,最好通过将其值设置为null来释放引用
解除一个值的引用并不意味着自动挥手该值所占用的内存。接触引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
小结
- 变量分两种类型:基本类型值和引用类型值
- 基本类型:Undefined,Null,Boolean,Number,String
- 基本类型值在内存中占据固定大小,保存在栈内存中
- 复制基本变量会创建值的副本
- 引用类型的值是对象,保存在堆内存中
- 引用类型值并不包含对象本身,是指向该对象的一个指针
- 复制引用类型实则复制指针,两个变量都指向同一个对象
- typeof、instanceof、Object.prototype.toString()
- 所有变量都存在一个执行环境(作用域)中,决定了变量的生命周期,以及哪部分代码可以访问
- 执行环境有全局执行环境和函数执行环境之分
- 作用域链:用于搜索变量和函数
- 局部环境可以访问父环境,反之则不行
- 变量的执行环境有助于确定何时释放内存
- 垃圾收集
- “标记清除”是主流的垃圾收集算法:给当前不使用的值加上标记,然后回收其内存
- ”引用计数“:跟踪记录所有值被引用的次数