详解javaScript闭包

闭包(closure)是javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

闭包的特性

  1. 函数嵌套函数
  2. 函数内部可以引用外部的参数和变量
  3. 参数和变量不会被垃圾收回机制回收

闭包的定义及优缺点

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

闭包的缺点就是常驻内存,会增加内存使用量,使用不当很容易造成内存泄漏。

闭包是javascript语言的一大特点,主要应用闭包场合主要是为了,设计私有的方法和变量。

一般函数执行完毕后,局部活动对象就被销毁,内存中仅仅保存全局作用域。但闭包的情况不同。

嵌套函数的闭包

function aaa(){
var a =1;
return function(){
alert(a++)
};
}

var fun = aaa();

fun();//1执行后a++,然后a还在
fun();//2
fun = null;//a被回收

闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗。

javascript的垃圾回收原理

(1)在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
(2)如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。

使用闭包的好处

  1. 希望一个变量长期驻扎在内存中
  2. 避免全局变量的污染
  3. 私有成员的存在

ge.

全局变量的累加

<script>
var a=1;
function abc(){
            a++;
            alert(a);
}
abc();
abc();
</script>

局部变量

<script>

function abc(){
var a=1;
a++;
alert(a);
}

abc();//2
abc();//2
</script>

那么怎么才能做到变量a既是局部变量又可以累加呢?

局部变量的累加

<script>
function outer(){
var x =10;
return function(){          //函数嵌套函数
x++;
alert(x);
}
}

var y =outer();
y();//y函数调用一次,结果为11,相当于outer()();
y();//y函数调用第二次,结果为12,实现了累加
</script>

函数声明与函数表达式

在js中我们可以通过关键字function来声明一个函数:

<script>

function abc(){
alert(123);
}
abc();
</script>

声明函数表达式:

<script>
(function(){
alert(123);
})();  //然后通过()直接调用前面的表达式即可
</script>

模块化代码,减少全局变量的污染

<script>
var abc = (function(){
    var a =1;
    return function(){
    a++;
    alert(a);

    }

})();

abc();//2; 调用一次abc函数,其实是调用里面内部函数的返回值
abc();//3;

</script>

私有成员的存在

    <script>
    var aaa = (function(){
    var a = 1;
    function bbb(){
    a++;
    alert(a);
    }

    function ccc(){
    a++;
    alert(a);
    }
    return{      //json结构
    b:bbb,
    c:ccc
    }
    })();

    aaa.b(); //2
    aaa.c(); //3
    </script>

使用匿名函数实现累加

//使用匿名函数实现局部变量驻留内存中,从而实现累加

<script type=""text/javascript>

function box(){
var age = 100;
return function(){
age ++;
return age;
};

};

var b = box();
alert(b());
alert(b()); //即alert(box()());
alert(b());
alert(b);   // function(){
            // age++;
            // return age;
            //  }

b = null;   //解除引用,等待垃圾回收
</script>

过度使用闭包会导致性能的下降。函数里放匿名函数,则产生了闭包

在循环中直接找到对应元素的索引

    <head>
    <body>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>  
        </ul>
    </body>
    </head>
<script>
    window.onload = function(){
    var aLi = document.getElementByTagName("li");
    for (var i=0;i<aLi.length;i++){
    aLi[i].onclick = function(){ //当点击时for循环已经结束
    alert(i);
    }
    }

    }
</script>

使用闭包改写上面的代码

<script>
        window.onload = function(){
        var aLi = document.getElementByTagName("li");
        for (var i=0;i<aLi.length;i++){

    (function(i){
        aLi.onclick = function(){
        alert(i);

        }
        })(i);
        }

        }
    </script>

内存泄漏问题

由于IE的js对象和DOM对象使用不同的垃圾收集方法,因此闭包在IE中会导致内存泄漏问题,也就是无法销毁驻留在内存中的元素

function closure(){
var oDiv = document.getElementById("oDiv");//oDiv用完之后一直驻留在内存中
oDiv.onclick =function(){
    alert('oDiv.innerHTML');
    };

}

closure();

//最后应将oDIV解除引用来避免内存泄漏

    function closure(){
    var oDiv = document.getElementById('oDiv');
    var test = oDiv.innerHTML;
    oDiv.onclick = function(){
    alert(test);
    };
    oDiv = null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值