zoukankan      html  css  js  c++  java
  • 理解闭包

    前面的文章曾经说到过闭包的问题,参见《闭包导致的问题》,今天回头看看,并没有介绍到闭包,仅仅提到了闭包的概念而已。

    首先我们得理解在javascript中,什么是闭包?

    谈到闭包,就必然要涉及变量,在javascript中,变量一般分为全局变量和局部变量。从我的角度(初学者角度)来理解的话,其实闭包的主要作用在于封装变量为局部变量,减少到全局作用域的污染。

    那么,究竟什么是闭包呢?

    function outer (){
         //  定义一些变量
        function inner(){
        //  内部函数执行代码块
        }  
    }

    从上面的代码来理解闭包的定义,如果要产生闭包的效果,就必须能够在outer外部调用到inner,放在后面再说,这里仅仅理解闭包的概念。

    outer函数定义了一个作用域,在这个作用域内声明了函数inner,函数inner能够影响到的范围,或者说可以调用到的变量所在的区域(当然也能引用到全局作用域变量),就是inner闭包。

    用一张图片来描述的话,红色边框表示该函数的作用域范围,而里面的半透明填充色即为外部函数的内部声明函数的闭包范围,其实闭包就相当于父函数的作用域。

    当我们将inner函数传递到outer函数外部调用的时候,就产生了闭包,这个闭包其实就是outer函数的作用域,这样,就能够全部定义局部变量,从而减少全局变量的定义。

    再举一个闭包常见的例子:循环遇到定时器,或者事件处理函数,这里举定时器的例子。

        function foo() {
            for (var i = 0; i < 3; i++) {
              setTimeout(function () {
                  console.log(i);
              }, 1000);
            }
          }
          foo();
    

    打开控制台可以看到,会打印三个3出来,而不是我们所期望的相隔1秒,分别打印0,1,2。

    这里其实就是当执行到延迟定时器内部函数块console.log(i)时,循环已经结束,此时i=3,而不是延迟定时器在执行时,分别创建作用域,所以这里必然结合闭包,给每次循环单独创建一个作用域,

        function foo() {
            for (var i = 0; i < 3; i++) {
              (function (i) {
                setTimeout(function () {
                    console.log(i)
                }, 1000);
              })(i);
            }
          }
          foo();

    如此,就能实现相隔1秒分别打印0,1,2。

    只要理解了闭包的概念,再去看各种涉及到闭包的例子,应该比较容易理解javascript中的痛点--闭包--了。

  • 相关阅读:
    poj1830 开关问题
    poj1681 Painter's Problem
    poj1222 EXTENDED LIGHTS OUT
    bzoj1923 [Sdoi2010]外星千足虫
    bzoj1013 [JSOI2008]球形空间产生器sphere
    poj2888 Magic Bracelet
    poj2409 Let it Bead
    poj1286 Necklace of Beads
    bzoj1004 HNOI2008 Cards
    bzoj2040 [2009国家集训队]拯救Protoss的故乡
  • 原文地址:https://www.cnblogs.com/zhuhuoxingguang/p/6400217.html
Copyright © 2011-2022 走看看