JavaScript基础|变量作用域和内存

基本类型和引用类型的简单介绍

  • 基本类型:存放在栈内存中的简单数据段。数据大小确定,内存空间大小可以分配。5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。
  • 引用类型:存放在堆内存中的对象,变量中实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。对象可以动态地创建属性。
复制
  • 复制基本类型的变量:两者不会互相影响
var num1 = 5; var num2 = num1; num1 = 2; //num1 = 2; num2 = 5;

  • 复制引用类型的变量:复制的只是对象变量保存的地址指针,所以两个对象变量会互相影响。
  • 函数的参数只能按值传递:注意,基本类型传递的是里面保存的基本类型的值,对象传递的是堆内存中的地址。非引用传递指的是:两个变量之间的引用,可以理解为是参数的别名。
检测类型: typeof能检测Boolean、String、Number、Undefined, Function; 对于null和引用类型,则统一返回Object。
instanceof可以检测引用类型的具体值: x instanceof Array\Object\RegExp等等。
Object.prototype.toString.call(x):可以精确判断变量类型了解详情
执行环境和作用域
  • 作用域链的底端始终是window对象,前端始终是当前执行的代码所在的环境的变量对象,每个执行环境都可以向上搜索作用域链,不可以向下搜索。
  • 【JavaScript基础|变量作用域和内存】延长作用域链可以使用:with语句可以将location变量对象加入到作用域链的最前端。with(location) { var url = href+"?h=1"} 这里的href指的就是location.href
  • 没有块级作用域(由花括号封闭的代码块):如果初始化变量没有var声明,则会自动添加到全局环境。
垃圾回收
  • 标记清除策略:
    首先把内存中所有的变量都做标记,之后会去掉当前环境中的变量以及被环境中的变量引用的变量的标记。在此之后还被标记的变量则是准备清除的变量,因为这些变量已经无法被环境访问到了。垃圾收集器完成内存清除工作。
    主要思想: 给不使用的变量加上标记,然后再回收其内存
  • 引用计数策略:
    跟踪记录每个值被引用的次数,当引用类型值被赋给了一个变量后,该值的引用次数就是1。如果同时这个值又被赋给了另一个变量,这个值的引用次数就变成了 2。相反,如果包含了这个值的引用变量又取得了另一个值,则这个值的引用次数减一。当某一个值的引用次数为0的时候,垃圾回收器就会回收这个值,释放这 个值所占用的内存。
    主要思想: 跟踪记录所有的值被引用的次数

    推荐阅读