1. 变量
    1. 变量
      1. 基本类型
        1. Undefined
        2. Null
        3. Boolean
        4. Number
        5. String
        6. 按值访问的,可以操作保存在变量中的实际值
      2. 引用类型
        1. 由多个值构成的保存在内存中的对象
        2. 在操作对象时是在操作对象的引用而不是实际的对象
        3. 引用类型是按引用访问的
        4. 对引用类型的值,可以为其动态添加属性和方法
    2. 复制变量值
      1. 基本类型
        1. 会在变量对象上创建一个新值,然后把该值复制到新变量分配的位置上
        2. 这两个变量可以参与任何操作而不会相互影响
      2. 引用类型
        1. 会将存储在变量对象中的值复制一份到新变量分配的空间中
        2. 复制结束后,两个变量实际上引用同一个对象
        3. 改变其中一个变量,就会影响另一个变量
    3. 传递参数
      1. 基本类型
        1. 被传递的值会被复制给一个局部变量
      2. 引用类型
        1. 在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数外部
        2. 对象在参数中是按值传递的
    4. 检测类型
      1. 基本类型
        1. typeof()
      2. 引用类型
        1. instanceof()
  2. 执行环境及作用域链
    1. 执行环境
      1. 执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为
      2. 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中
      3. 全局执行环境是最外围的一个执行环境
        1. 在web浏览器中,全局执行环境被认为是window对象
        2. 所有全局变量和函数都是作为window对象的属性和方法创建的
      4. 当执行流进入一个函数时,函数的环境会被推入一个环境栈中。在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境
      5. 当代码在一个环境中执行时,会创建变量对象的一个作用域链
    2. 作用域链
      1. 作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问
      2. 作用域链的前端始终是当前执行的代码所在环境的变量对象
      3. 全局执行环境的变量对象始终都是作用域中的最后一个对象
      4. 在局部作用域中定义的变量可以在局部环境下与全局变量互换使用
      5. 内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中的任何变量和函数
      6. 延长作用域链
        1. 当执行流进入下列任何一个语句时,作用域链会得到加长
          1. try-catch语句的catch块,它会创建一个新的变量对象,其中包含的是被抛出的错误对象声明
          2. with语句,它会将指定的对象添加到作用域链中
      7. 没有块级作用域
        1. if语句中定义的变量声明会将变量添加到当前的执行环境中
        2. for语句中创建的变量i即使在for循环执行结束后,依旧会存在于循环外部的执行环境中
        3. 声明变量
          1. 使用var声明的变量会自动被添加到最接近的环境中
          2. 如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境中
        4. 查询标识符(变量实际代表的值)
          1. 当在某个环境中为了读取或写入而引用一个标识符时,必须通过搜索来确定该标识符实际代表什么,搜索过程从作用域链的前端(即当前环境)开始,闲上逐级查询与给定名字匹配的标识符
          2. 任何位于局部变量color之后的代码,不使用window.color都无法访问全局变量color
  3. 垃圾收集
    1. 标记清除
      1. JavaScript中最常用的垃圾收集方式
      2. 当变量进入环境时,就将变量标记为进入环境。永远不能释放进入环境的变量所占用的内存。当变量离开环境时,将其标记为离开环境
    2. 引用计数
      1. 不常见
      2. 如果一个函数中两个对象互相引用各自属性,它们的引用次数永远不会是0,如果这个函数被多次调用,会导致大量内存得不到回收
      3. 只要在IE9以下版本中涉及COM对象,就会存在循环引用问题
    3. 管理内存
      1. 一旦数据不再有用,最好通过将其值设置为null来释放其引用(这个方法叫解除引用)
      2. 解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收