zoukankan      html  css  js  c++  java
  • 有关闭包的总结

     

     

     

    闭包的应用场景一

    闭包的应用场景二

    闭包的应用场景三

    [Don't use closures unless you really need closure  semantics.]不要使用闭包,除非你真正需要它。

    [In most cases, non-nested functions are the right way to go.]请使用无嵌套函数。

    -------------------------------------------

    什么是闭包?

    复制代码
    function a(){
    var i=0;
    function b(){
    alert(i);
    }
    return b;
    }
    var c = a();
    c();
    复制代码

    全局变量c指定对 函数a的内部函数b的引用;内部函数b的执行需要依赖函数a的资源;

    这里就产生一个闭包,使得a在执行完毕并返回后,不会被javascript垃圾回收机制GC回收。

    因为这里c还在引用着b,而b依赖着a,故a在使用后,仍然存在于内存中。

    简而言之:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

    闭包的应用场景

      1.使用闭包代替全局变量

      2.函数外或在其他函数中访问某一函数内部的参数

      3.在函数执行之前为要执行的函数提供具体参数

      4.在函数执行之前为函数提供只有在函数执行或引用时才能知道的具体参数

         5.为节点循环绑定click事件,在事件函数中使用当次循环的值或节点,而不是最后一次循环的值或节点

         6.暂停执行

         7.包装相关功能

    1.使用闭包代替全局变量

       全局变量有变量污染和变量安全等问题。

    复制代码
    //全局变量,test1是全局变量
    var test1=111
    function outer(){
    alert(test1);
    }
    outer(); //111
    alert(test1); //111
     
     
     

    //闭包,test2是局部变量,这是闭包的目的
    //我们经常在小范围使用全局变量,这个时候就可以使用闭包来代替。
    (function(){
    var test2=222;
    function outer(){
    alert(test2);
    }
    function test(){
    alert("测试闭包:"+test2);
    }
    outer(); //222
    test(); //测试闭包:222
    }
    )();
    alert(test2); //未定义,这里就访问不到test2
    复制代码

      

    2.函数外或在其他函数中访问某一函数内部的参数

       为了解决在Ajax callback回调函数中经常需要继续使用主调函数的某一些参数。

    复制代码
    function f1(){
    var test=111;
    tmp_test=function(){return test;} //tmp_test是全局变量,这里对test的引用,产生闭包
    }

    function f2(){
    alert("测试一:"+tmp_test());
    var test1=tmp_test();
    alert("测试二:"+test1);
    }
    f1();
    f2();
    //测试一:111
    //测试二:111
    alert(tmp_test()); //111
    tmp_test=null;
    复制代码

      

    3.在函数执行之前为要执行的函数提供具体参数

    某些情况下,是无法为要执行的函数提供参数,只能在函数执行之前,提前提供参数。

    有哪些情况是延迟执行?

    如:setTimeOut 

         setInterval

         Ajax callbacks

         event handler[el.onclick=func 、 el.attachEvent("onclick",func)]

    复制代码
    //无法传参的情况
    var parm=222;
    function f1(){alert(111)}
    function f2(obj){alert(obj)}
    setTimeout(f1,500);//正确,无参数
    var test1=f2(parm);//执行一次f2函数
    setTimeout(f2,500);//undefined,传参失败
    setTimeout(f2(parm),500);//参数无效,传参失败
    setTimeout(function(parm){alert(parm)},500);//undefined,传参失败
    document.getElementById("hello").onclick=f1;//正确
    document.getElementById("hello").attachEvent("onclick",f1);//正确
     

    //正确做法,使用闭包
    function f3(obj){return function(){alert(obj)}}
    var test2=f3(parm);//返回f3的内部函数的引用
    setTimeout(test2,500);//正确,222
    document.getElementById("hello").onclick=test2;//正确,222
    document.getElementById("hello").attachEvent("onclick",test2);//正确,222
    复制代码
  • 相关阅读:
    动态演示面动成体:圆柱、圆锥、圆台、球——GeoGebra制作教程
    修改图形颜色
    圆柱面的指令生成之一--------参数方程
    使用 EPPlus 封装的 excel 表格导入功能 (二) delegate 委托 --永远滴神
    使用 EPPlus 封装的 excel 表格导入功能 Func--小试牛刀
    markdown画图
    redis cluster集群搭建
    IQueryable的简单封装
    为 linux 换源
    解决dotnet-Angular的跨域(cors)问题
  • 原文地址:https://www.cnblogs.com/dujishi/p/5878816.html
Copyright © 2011-2022 走看看