请选择 进入手机版 | 继续访问电脑版
查看: 138|回复: 1

关于javascript闭包的最通俗易懂的理解

[复制链接]
  • TA的每日心情
    开心
    8 小时前
  • 签到天数: 1574 天

    [LV.Master]伴坛终老

    4248

    主题

    6170

    帖子

    10万

    积分

    管理员

    IBC编程社区-原道楠

    Rank: 9Rank: 9Rank: 9

    积分
    108846

    推广达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2019-10-24 09:50:30 | 显示全部楼层 |阅读模式

    马上加入IBC,查看更多教程

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    这两天在研究闭包,网上一通找,有牛人写的帖子,有普通人写的帖子,但是大多没戳中本小白所纠结的点,而且大多插入了立即执行函数,其实根本不须要的,反而让人产生了误解。这里我用我的方式解说一下闭包。
    1.目的:保证局部变量常驻在内存中,且只能通过固定的方式访问,不可以被所有人访问,算起来也算是个只能被指定对象访问的专用型全局变量。
    2.实现方式:在函数f1中返回一个内部定义的函数f2,后通过利用返回出来的函数f2来操作f1中定义的局部变量。

    下面我来从各种刁钻的角度来举例详细阐明,包学包会!看完例子以后再看上面说的目的和实现方式就会有种豁然开朗的感觉了!
    round 1:
    function add() {
                      var x = 0;
                      return function () {
                            return ++x;
                      }
            };

    var temp=add();//此处的add()的括号和function add()的括号表达的意思是完全差别的,在此处add体现上面定义的函数,add()体现执行一次上面定义的函数,这一点很关键!
             //执行一次的效果就是返回了函数 function () {return ++x;},但是请注意!这里返回的仅仅是函数本身,也就是此时函数尚未执行,故此时x=0
    temp();//执行一次返回的函数,++x,此时x=1
    console.log(temp());//再次执行一次返回的函数,此时x=2,且输出了函数的返回值2,可以在控制台中看到

    这就完成了闭包了,add函数中的x常驻内存,且我可以在add函数外部通过调用它返回的函数来操作这个x,如果看懂了下面可以不看,如果看了其他帖子有一些其他的异或好比立即执行函数之类的可以看看下面的,你很快就不会迷惑了!
    round 2:
    var temp = function add() {
                  var x = 0;
                  return function () {
                        return ++x;
                  }
            };//此处temp体现函数add函数本身,但是尚未执行。
            var temp1 = temp();//执行temp函数,返回函数 function () {return ++x;},但尚未执行该函数,故x=0
            temp1();//执行temp1,此时执行了一次function () {return ++x;},故x=1
            console.log(temp1());//再次执行一次function () {return ++x;},此时x=2,且输出到了控制台

    这一回合是为下面的立即执行函数做铺垫,下面立即执行函数版本隆重登场!当当当当!
    round 3:
    var temp = (function add() {
                  var x = 0;
                  return function () {
                        return ++x;
                  }
              })();//仔细看,此处为(fucntion add(){})(),此处执行了立即执行函数,也就是说返回给temp的与round2返回的add函数本身差别,而是返回的 function () {return ++x;}
            temp();//顺理成章的,这里直接执行temp,就是执行了function () {return ++x;},故x=1
            console.log(temp());//同理x=2
    颠末上面三个例子的解说想必你已经胸有定见了,但是肯定还是存在迷惑的,好比说round1中var temp=add();,我不把add()的效果赋给temp直接执行行不可?答案是否定的,有一点肯定要认知清晰,函数是对象,这一点至关紧张,否则将会走入误区。下面举例阐明:
    这个是round1的改版:
    function add() {
      var x = 0;
      return function () {
        return ++x;
      }
    };
    console.log(add()());//输出1
    console.log(add()());//输出1

    为什么会这样呢?关键点在于函数是对象,上面实验了两次add()(),在这两次中,add()返回的对象是不一样的,以是他们各自再执行add()()就是为各自的局部变量x加1,以是才两次都输出1,如果改一下
    function add() {
                var x = 0;
                return function () {
                    return ++x;
                }
            };
            var temp1 = add();
            var temp2 = add();
            console.log(temp1());//输出1
            console.log(temp1());//输出2
            console.log(temp2());//输出1
            console.log(temp2());//输出2

    这样是不是就明确了,同理add函数也不能写成下面这种情势:
    function add() {
      var x = 0;
      return (function () {
        return ++x;
      })()
    };
    否则返回的只是一个常量而不是一个对象了。希望这篇文章能给跟我一样在探索闭包的小白一点开导,嘿嘿嘿






    来源:https://www.cnblogs.com/wuhao19950102/archive/2019/10/23/11726650.html
    C#论坛 www.ibcibc.com IBC编程社区
    C#
    C#论坛
    IBC编程社区
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则