简单谈谈javascript中的变量、作用域和内存问题(2)

  [4.1]作用域链的特点:内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数。这些环境之间的联系是线性、有次序的。每个环境都可以向上搜索作用域链,以查询变量和函数名;但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。

[5]延长作用域链:

  [5.1]try-catch语句:catch块会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明
  [5.2]with语句:会将指定的对象添加到作用域链中

function buildUrl(){ var qs = '?debug=true'; with(location){ var url = href + qs; } return url; }

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

[1]垃圾回收机制:找出那些不再继续使用的变量,然后释放其占用的内存,垃圾收集器会按照固定的时间间隔,或代码执行中预定的收集时间,周期性地执行这一操作

[2]垃圾收集标记无用变量的两种策略

  [2.1]标记清除,标记“进入环境”和“离开环境”。离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除
  [2.2]引用计数,跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1,如果同一个值又被赋给另一个变量,则该值的引用次数加1,相反,如果包含对这个值的引用的变量又取得了另外一个值,则这个值的引用次数减1,当这个值的引用次数为0时,则说明没有办法再访问这个值了,因此就可以将其占用的内存空间回收回来。
    [2.2.1]引用计数的问题:循环引用:对象A中包含一个指向对象B的指针,对象B中也包含一个指向对象A的指针
    [2.2.2]IE:IE中有一部分对象并不是原生js对象,例如,其BOM和DOM中的对象就是使用c++以COM对象的形式实现,而COM对象的垃圾回收机制采用的就是引用计数策略

var element = document.getElementById('some_element'); var myObject = new Object(); myObject.element = element; element.someObject = myObject;

    解决办法:为了避免类似这样的循环引用,最好是在不使用它们的时候手工断开

myObject.element = null;
element.someObject = null;   
    为了解决此问题,IE9把BOM和DOM对象都转换成了真正的js对象

【内存管理】

[1]主要问题:分配给web浏览器的可用内存数量通常要比分配给桌面应用程序的少,目的是防止运行js的网页耗尽全部系统内存而导致系统崩溃。内在限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量 

[2]优化方式:为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用,这种做法叫解除引用。这一做法适用于大多数全局变量和全局对象的属性以及循环引用变量,局部变量会在它们离开执行环境时自动被解除引用。

解除变量的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wggjds.html