闭包的故事

一、什么是闭包  

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

五、结束语

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

原文地址:https://www.cnblogs.com/sanweimiao/p/6533216.html