JavaScript 闭包的作用

日期: 2017-07-20         浏览量: 2976

在实际开发中闭包的运用非常广泛。


封装变量:


闭包可以帮助一些不必要暴露在全局的变量封装成 “ 私有变量” 。假设有一个设计计算乘积的简单函数:


var mult = function(){

    var a= 1;                        //私有变量

    for(var i = 0 ; i<arguments.length; i++){

        a = a*arguments[i];

    }

    return a;

}

 

console.log(mult(1,2,3));            //6


mult 接受一些 number 类型的参数,并返回这些参数的乘积。现在我们觉得对于那些相同的参数来说,每次有计算是一种浪费,我们可以加入缓存机制来提高整个函数性能


var mult = (function(){

    var cache = {};

    return function(){

        var args = Array.prototype.join.call(arguments, ' , ');

        if(args in cache){

            return cache[args];

        }

        var a = 1;

        for(var i = 0; i<arguments.length; i++){

            a = a * arguments[i];

        }

        return cache[args] = a;

    }

})();

console.log(mult(1,23,4));        // 输出 92


提炼函数是代码重构的一种常见技巧。如果大函数中有一些代码块可以独立出来,我们会常常把这些代码块封装在独立的小函数里面。独立的小函数有利于代码的复用。我们把上面代码重构下吧


var mult = (function(){

    var cache = {};

    //封装 calculate 函数

    var calculate = function(){

        var a =1;

        for(var i = 0 ; i<arguments.length ; i++){

            a = a* arguments[i];

        }

        return a;

    }

    

    return function(){

        var args = Array.prototype.join.call(arguments, ',');

        if(args in cache){

            return cache[args]

        }

        return cache[args] = calculate.apply(null , arguments);

    }

})()


console.log(mult(1,3,4));          //输出 12



延续局部变量的生命周期:


img 对象经常用于进行数据上报 ,如下示例。

var report = function( src ){

    var img = new Image();

    img.src = src;

}

report( 'http://XXX.com/getInfo' );


但是通过后台记录查询我们得知,因为一些低版本浏览器的实现存在bug,在一些浏览器下使用 report 函数上报数据会丢失30%左右数据。也就是说 report 函数并不是每一次都能成功发起 http 请求。丢失原因是 img 是 report 函数的局部变量,当函数调用结束后 img 局部变量随机销毁,而此时还没有来的及发送http请求。

现在我们把 img 变量 使用闭包封闭起来,便能解决此问题.


var report = (function(src){

    var imgs = [];

    return function(){

        var img = new image();

        imgs.push = img;

        img.src = src;   

    }

})();