zoukankan      html  css  js  c++  java
  • 闭包的故事

    一、什么是闭包  

      曾经有这样一位“兄弟”,他不显山不露水,但在编码家族却往往需要他的帮助,像谜一样很难看懂,可当你真正去了解他时,却又发现他比想象中简单得多。他就是闭包,英文名叫closure。

      在百度中是这样介绍他的:闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。反正我是看不懂,所以,我就按照自己的理解来说说闭包到底是什么。

    二、闭包的由来  

      说到闭包,就得先提提作用域,他有全局变量和局部变量。在函数内部可以访问到的外部的变量是全局变量,但在函数外部不可以使用函数内部的变量,也就是局域变量。

     

    <script>
        var a=10;
        function num(){
            var b=3;
            return b;
        }
      console.log(b);
    </script>

     

    代码中a就是全局变量,在函数内部的b就是局部变量,所以当执行代码的时候,系统会报错说b找不到。那么如何在函数的外部去得到局部变量的值呢?这就引出了我们要了解的闭包。

    三、闭包的使用  

      闭包就是能够读取其他函数内部变量的函数,在本质上闭包就是将函数内部和函数外部连接起来的一座桥梁,方法就是在函数内部再定义一个函数。举个栗子:

    <script>
        function func1(){
            var num=10;
            return num;
        }
        console.log(num);
    </script>

    这样打印出来的结果是num is not defined,也就是说调用不到函数内部的num值,而外部又没有声明num,因此找不到,所以要在内部再定义一个函数,像下面这样:

    <script>
        function func1(){
        var num=20;
        function func2(){
            return num;
        }
        return func2;
        }
        var result=func1();
        console.log(result());    
    </script>
    <script>
        function func1(){
        var num=20;
        function func2(){
            return num;
        }
        return func2();
        }
        var result=func1();
        console.log(result);    
    </script>

    注意:当内部函数的func2以func2()的方式调用是,result直接输出即可,若func2没有调用,最后的result需要再调用一次,最后出来的结果就是20啦!看懂了吗?

    四、闭包的实例  

      你以为只是这样吗?闭包还有变量持久化的作用,就是变量的值会始终保存在内存中,比如:

    <script>
        function fn1(){
        var num=18;
        function fn2(){
            return ++num;
        }
        return fn2;
        }
        var result=fn1();
        console.log(result());
        console.log(result());
        console.log(result());
    </script>

    这样打印出来的结果是19、20、21,因为他的变量持久化,所以第一次执行出来的19会保存下来,在下次调用的时候,num就变成了19,然后进行下面的函数,于是出现了20、21。

      但他的优点也会变成缺点,那就是因为他的变量持久化,使得函数中的局部变量始终都被保存在内存中,因此内存消耗很大,所以虽然好用,还是不能滥用闭包,否则会造成网页的性能问题。

      关于他的应用场景就是类似上面那样的实现局部变量自增,还有个课堂小例子就是点击ul下的li显示下标,like this:

    <script>
        var ali=document.querySelectorAll("ul li");
        for(var i=0;i<ali.length;i++){
            ali[i].onclick=(function(index){
                return function(){
                    alert(index);
                }
            })(i)
        }
    </script>    

    五、结束语

      关于我所了解的闭包就是这个样子,能通过在函数内部在套一个函数来获取到原本函数内部的局部变量。当然还是要多练习才会理解的更透彻,练多了就会发现其实闭包一点也不难。

  • 相关阅读:
    Unity快速运行模式与减少编译等待时间
    神器 Trello Bug Tracker 使用介绍
    优化UGUI的ScrollRect
    Unity开源搜索引擎
    游戏技术分享网站 CEDEC
    帧同步技术总结
    Unity Text自动缩放文本
    系统知识坑洼之旅文件系统篇其一文件夹也是个文件?
    [代码修订版] Python 踩坑之旅进程篇其五打不开的文件
    [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼
  • 原文地址:https://www.cnblogs.com/sanweimiao/p/6533216.html
Copyright © 2011-2022 走看看