zoukankan      html  css  js  c++  java
  • JavaScript之闭包

     这次是一篇读后感

    深入理解javasrcipt原型和闭包(15)——闭包

    Javasrcipt秘密花园——函数之闭包和引用

    通读两篇关于闭包的文章之后,还是有点收获的,就总结一下,怕自己忘记

    好,下面开始我的表演

    闭包是什么?

    闭包是 JavaScript 一个非常重要的特性,这意味着当前作用域总是能够访问外部作用域中的变量。

    (而在通常情况下当前作用域只能访问本身或者上级的作用域),作用域这一部分下次再写

    函数是 JavaScript 中唯一拥有自身作用域的结构,所以闭包的创建依赖于函数。

    闭包的时候,函数有两种情况,

    一种是函数作为返回值

    一种是函数作为参数传递

    1。函数作为返回值

    function nihao(){
    var i=0;
    return  function get(i){
        i++;
        return i;
    }
    }
    var f=nihao();
    f(1);

    我们在控制台执行之后结果如下

    执行结果为2

    我们把get函数作为返回值赋值给变量f,执行f(1)的时候,直接进入到get的作用域下,1赋值给i,执行完i++,i变为2,之后return i

     2。函数作为参数传递

    var a=2,b=function(c){
          if(c>a){
          console.log(c);  
    }     
    };
    (function(f1){
        var a=5;
        f1(3)
    })(b);

    我们在控制台打印一下

    结果为3,

    可以看到,我们执行了一个匿名包装器(自执行匿名函数),然后把函数b作为参数传到了匿名函数里面。

    执行f1(3)其实就是在执行b=function(3)

    这里有一个问题,我们在匿名包装器内执行的时候,a已经重新定义为5,但是在执行到f1的时候,a又变为了2,所以3>2成立,执行了console.log

    根据执行结果,我是这么理解的,当调用f1函数的时候,其实就是进入b=function()的作用域下了,而b又是通过函数赋值表达式定义的函数

    所以,函数b和a其实是在同一个作用域下的,这个时候也会执行var a=2;等于就是重新定义了一下a,所以当执行if(c>a)的时候,a就已经重新定义为2 

    以为已经结束了?

    错,我又去用函数声明的方式测试了一下结果

    是的,就算通过函数声明的方式定义的b也一样结果为3

    所以这个和函数的定义方式无关,无论是函数声明还是函数赋值表达式来定义,结果都是一样的

    那么只能这么理解了

    当我们执行f1(3)的时候,作用域就已经改变了,从匿名包装器中的作用域转移到了function b() 或者说var  b=function()所在的作用域中了

    接着会执行if判断,会寻找a,在函数b中没找到,然后向父级中寻找,这里定义了一个var a=2;这个时候a就找到了,然后继续执行if语句

    3>2,接着执行console.log,输出3

    总结了,两个又好像没有总结,完了,

    算了,先写下一个把

    好,我们看在秘密花园中是这么写的

    function Counter(start) {
        var count = start;
        return {
            increment: function() {
                count++;
            },
    
            get: function() {
                return count;
            }
        }
    }
    
    var foo = Counter(4);
    foo.increment();
    foo.get(); 

    看一下执行结果

    我们来分析一下,这个什么鬼的执行顺序,

    首先通过函数赋值表达式的方式把Counter方法赋值给变量foo,那么foo现在也是一个函数了

    因为 JavaScript 中不可以对作用域进行引用或赋值,因此没有办法在外部访问 count 变量。 唯一的途径就是通过闭包。

    赋值的时候还传了一个参数4,那么我们执行foo.increment()的时候,这个时候已经就是闭包了,

    所以count就为4,然后执行了count++;

    接着执行foo.get();进入了第二个闭包,会返回count,因为count++了所以这个时候count就为5,return count,返回的就是5;

    这么理解没错吧

    我先这么写,晚点发现不对了,再编辑一下

  • 相关阅读:
    for循环里面不要进行remove操作,for循环里remove元素后,list的下标会减小,导致遍历不完全
    elasticsearch,java api, transport Client, 查询时索引库可以用通配符*和删除接口不能用
    (一)WebPack4.0 从零开始
    合并代码 dev 到 master
    vscode 终端无法输入问题 看这个就行了
    node 学习笔记:一、 nvm 安装管理Node版本
    常见的对象创建模式
    深入理解闭包
    sort对数组排序
    图片压缩
  • 原文地址:https://www.cnblogs.com/WhiteM/p/7481282.html
Copyright © 2011-2022 走看看