美文网首页
理解闭包经典例子

理解闭包经典例子

作者: qxz9 | 来源:发表于2018-03-10 23:09 被阅读0次

    闭包,很多人对它的定义和理解都不一样,关于它的文章比比皆是,但是要真正意义上的理解它,还是有些难度的。对于闭包的定义,我也不敢妄下定论,所以这篇文章只是提及关于闭包的几个经典例子。
    现阶段,我对于闭包的理解为:闭包是定义在一个函数内的另一个函数,这个函数可以访问外层函数中的局部变量,并将这个函数作为返回值return出去。

    计时器

    题目:定义一个定时器,计算点击网页的次数

    这个题目非常简单,想必大家都能写出来。

    var count = 0;
    function addCount() {
        count++;
    }
    document.body.addEventListener("click", addCount);
    

    count作为一个全局变量,其他地方都可以对它进行操作,如果其他地方对count重新赋值或者重新定义count,那么这个计时器就被破坏了。这时候,闭包就起作用了。

    function addCount() {
        var count = 0;
        var addCount = function() {
            count++;
       }
        return addCount;
    }
    document.body.addEventListener("click", addCount);
    

    将count作为一个局部变量,把addCount作为函数返回,这样,其他地方对count进行赋值或者重新定义,对计时器也不会有影响了。

    for循环中的i值

    我们先来看一段代码

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    
    var lis = document.getElementsByTagName("li");
    for (var i = 0; i < lis.length; i++) {
        lis[i].onclick = function() {
            console.log(i);
        }
    }
    

    运行这段代码后,大家或许会有疑问,为什么点击任一个li标签,console台打印的都是3。
    代码运行结束后,给每个li标签定义了click函数,但这个函数没有立即执行,只有当点击li时,才会执行该click函数;当点击li执行函数时,函数中的变量i没有在函数中定义,根据js的作用域链原则,会继续向上级作用域查询,因此找到了全局作用域中的i,这时for循环已经执行结束,此时全局作用域中的i已经变为了3,故打印出来的当然是3了。
    要想实现,打印出来的值为点击li的顺序值,这时,闭包又起到了作用

    var lis = document.getElementsByTagName("li");
    for (var i = 0; i < lis.length; i++) {
        lis[i].onclick = (function(i) {
           var clickLi = function() { 
               console.log(i);         
           }
           return clickLi;
        })(i)
    }
    

    在for循环执行时,立即将当前的i值作为形参传入clickLi中,而形参默认为函数内的局部变量,函数外部是不能对i进行操作的。所以,当点击li时,执行clickLi函数时,打印出来的则是li的顺序值。

    相关文章

      网友评论

          本文标题:理解闭包经典例子

          本文链接:https://www.haomeiwen.com/subject/zyobfftx.html