zoukankan      html  css  js  c++  java
  • 闭包及其作用

    闭包:有权访问其他函数内部变量的函数,在一个函数内部创建一个函数,就形成了闭包,闭包的参数和变量不会被垃圾回收机制回收。闭包可以避免全局变量的污染。

    使用场景:

    1.闭包的经典应用:绑定事件

    假如页面上有5个div,我们通过for循环来给每个div绑定一个事件,每点击一次输出它的索引值。如果没有使用闭包,在循环内部给每个节点添加事件,发现点击后每次输出的值都是一样的。因为onclick事件时异步触发的,当事件触发的时候for循环早就结束了。此时变量i的值是5,。解决办法就是在闭包的帮助下,把每次循环的i值包裹起来:使用立即执行函数将i值作为参数传递进去后再绑定事件

    var list=document.getElementById("list");
    for (var i = 0; i < list.length; i++) {
        (function(i){
            list[i].onclick=function(){
                console.log(i);
            }
        })(i);
    }

    2,封装变量:闭包可以帮助把一些不需要暴露在全局的变量封装成私有变量。

    在大型项目当中,为了防止命名冲突,一般会把相应的代码用闭包的形式包裹起来,避免暴露在全局作用域下

    假如有一个函数接受number类型的参数并返回这些参数的乘积,你应该怎么做。

    第一步你应该会写出下面的代码:

    var mult=function(){
        var a=1;
        for (var i = 0; i < arguments.length; i++) {
            a=a*arguments[i];
        }
        return a;
    };

    优化代码:假如缓存机制,如果参数相同直接返回这个缓存后的值

    var cache = {};
    var mult = function() {
        var args = Array.prototype.join(arguments, ',');
        if (cache[args]) {
            return cache[args];
        } else {
            var a = 1;
            for (var i = 0; i < arguments.length; i++) {
                a = a * arguments[i];
            }
            return cache[args] = a;
        }
    
    }

    继续优化:注意到cache这个变量只在这个函数内部被使用,与其让其和mult函数一起暴露在全局作用域下,还不如把它封装在函数内部,

    var mult = (function() {
        var cache = {}; //把原先的cache封装在函数的内部,这样可以减少页面内的全局变量
        return function() {
            var args = Array.prototype.join(arguments, ',');
            if (cache[args]) {
                return cache.args
            } else {
                var a = 1;
                for (var i = 0; i < arguments.length; i++) {
                    a = a * arguments[i];
                }
                return cache[args] = a;
            }
    
        }
    })(); //立即执行函数后return一个function

    提炼函数是代码重构中的一种常见技巧。如果在一个大函数中有一些代码块能够独立出来,那么我们将它封装在一个小函数当中,这样有助于代码复用,如果同时小函数有个好名字,那么也起到注释的作用。如果小函数不在程序的其他地方使用,那么将它放在闭包当中。

    var mult = (function() {
        var cache = {}; //把原先的cache封装在函数的内部,这样可以减少页面内的全局变量
        var caculate = 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(arguments, ',');
            if (cache[args]) {
                return cache[args];
            } 
            cache[args]=caculate.apply(null,arguments);//null指默认的宿主对象
    
        }
    })();

    3.延续局部变量的寿命

    用img对象来进行数据上报时,把img变量用闭包封闭起来,因为在低版本的浏览器用report函数上报数据时存在bug,会丢失数据。

    因为img是局部变量,函数执行完毕后局部变量随即被销毁,以至于来不及发出http请求,导致数据丢失。

    var report=(function(){
        var imgs=[];
        return function(src){
            var img=new Image();
            imgs.push(img);
            img.src=src;
        }
    })();
    report("url");//数据上报
  • 相关阅读:
    邻接表怎么写
    hiho一下 第二十五周(SPFA)
    hdu 1426 Sudoku Killer(DFS)
    hdu5147 (sequence 2) 树状数组
    hdu1233 prim
    输入输出外挂
    RMQ-ST求区间最值
    最近公共祖先(简单版)
    【Java】【20】后台发送GET/POST方法
    【实战问题】【11】导入Maven项目后报错,Project configuration is not up-to-date with pom.xml. Run project configuration update
  • 原文地址:https://www.cnblogs.com/t1amo/p/6767575.html
Copyright © 2011-2022 走看看