JavaScript入门教程

JavaScript简介
JavaScript语法基础
JavaScript流程控制
JavaScript函数
面向对象编程
JavaScript事件
JavaScript DOM
正则表达式
JavaScript BOM
AJAX

专题分析

浏览器兼容性
JS优化
Web前端开发规范
编辑器推荐
总结和笔记

学习助手

对象参考手册
ECMAScript分析
数据中心
QQ交流群

JS循环引用的内存泄露问题

如果循环引用中包含DOM对象或者ActiveX对象,那么就会发生内存泄露。内存泄露的后果是在浏览器关闭前,即使是刷新页面,这部分内存不会被浏览器释放。

简单的循环引用:
var el = document.getElementById('MyElement');
var func = function () {…}
el.func = func;
func.element = el;

但是通常不会出现这种情况。通常循环引用发生在为dom元素添加闭包作为expendo的时候。

如:
function init()
{
    var el = document.getElementById('MyElement');
    el.onclick = function () {……}
}
init();

init在执行的时候,当前上下文我们叫做context。这个时候,context引用了el,el引用了function,function引用了context。这时候形成了一个循环引用。

下面2种方法可以解决循环引用

  • 置空dom对象
    使用前:
    function init()
    {
        var el = document.getElementById('MyElement');
        el.onclick = function () {……}
    }
    init();

    使用后:
    function init()
    {
        var el = document.getElementById('MyElement');
        el.onclick = function () {……}
        el = null;
    }
    init();

    将el置空,context中不包含对dom对象的引用,从而打断循环应用。 如果我们需要将dom对象返回,可以用如下方法:

    使用前:
    function init()
    {
        var el = document.getElementById('MyElement');
        el.onclick = function () {……}
        return el;
    }
    init();

    使用后:
    function init()
    {
        var el = document.getElementById('MyElement');
        el.onclick = function () {……}
        try{ return el; }
        finally { el = null; }
    }
    init();
     
  • 构造新的context
    使服用前:
    function init()
    {
        var el = document.getElementById('MyElement');
        el.onclick = function () {……}
    }
    init();

    使用后:
    function elClickHandler() {……}
    function init() {
        var el = document.getElementById('MyElement');
        el.onclick = elClickHandler;
    }
    init(); 把function抽到新的context中,这样,function的context就不包含对el的引用,从而打断循环引用。