JavaScript作用域链和垃圾回收机制

作用域链

基本概念:  

  在了解作用域链和内存之前,我们先了解两个概念,分别是执行环境和变量对象。

  执行环境:定义变量或者函数有权访问的其他数据,决定了它们各自的行为。每个对象都有自己的执行环境。

  变量对象:包含执行环境中所有变量和函数都保存在这个对象中,每个执行环境都有一个与之关联的变量对象。但是我们无法访问。

作用域链:

  在我们了解这两个概念之后,我们来了解一下作用域链。

  作用域链主要是保证对执行环境有权访问的所有变量和函数的有序访问。作用域的前端,始终都是当前执行的代码所在环境的变量对象。作用域的下一个变量对象是来自外部执行环境,也就是包含这个执行环境的执行环境的变量对象,一直延伸到全局执行环境。

标识符解析:

  标识符解析就是沿着作用域链一级一级地搜索标识符的过程。这个过程始终都由前端(当前执行环境变量对象)开始,直到搜索到标识符或者全局执行环境变量对象为止。

延长作用域链:

  1. try-catch语句,创建一个新的变量对象,包括被抛出的错误对象。

  2. with语句,将指定的对象添加到作用域链中。

1 with(location) {
2     // location对象中的search属性,
3     // 由于将location添加到作用域链中,所有可以直接访问search
4     qs = search;
5 }

没有块级作用域:

  值得注意的一点是,在javascript中,没有块级作用域这个概念,只有函数作用域,用此在语句块中用var定义的变量会自动添加到最接近的执行环境中。(没有使用var定义的变量,将会添加到全局环境中,成为全局变量)

垃圾回收机制

  javascript具有自动垃圾回收机制,执行环境会负责管理代码执行过程中使用的内存。

垃圾回收机制的原理:

  找出那些不在继续使用的变量,然后释放其占用的内存空间。垃圾收集器会按照固定的时间间隔(或者代码执行中预定的收集时间),周期性的执行这一操作。

两种收集方式:

  1. 标记清除

  垃圾收集器在运行时,会给所有存储在内存中的变量进行标记,然后,去掉环境中的变量,以及被环境中的变量引用的变量的标记。在此之后,被加上标记的变量即为要被删除的变量。最后垃圾收集器完成内存清除工作,回收这些变量占用的内存。

  2. 引用计数

  跟踪每一个变量的值被引用的次数,当引用次数为0时,说明没办法访问这个值了,就回收这个变量占据的空间。

  存在一个问题:循环引用,即A引用B,B引用A。及时A,B已经不需要了,也无法释放A,B占用的内存。

  解决方法:手动接触引用(a=null)。

垃圾回收机制的性能问题:

垃圾回收器时周期性执行的,因此,确定垃圾收集器何时回收内存是很有必要的。IE之前的垃圾收集器时根据内存的分配量运行的。因此存在一个问题,如果内存占用量达到要求,且这些变量都是是有用数据,那么垃圾收集器就会不停的运行,导致严重的性能问题。IE7对其分配量阀值进行动态修正,如果回收的内存分配量少于15%,阀值加倍,如果回收的内存分配量大于85%,阀值恢复默认值。

原文地址:https://www.cnblogs.com/diligentYe/p/6480289.html