• JavaScript闭包


    之前讲闭包的文章,很多初学者,还是没懂,还是在写一篇。原文地址:http://www.w3cfuns.com/blog-5471724-5409375.html
    先说句题外话,你看完之后,觉得讲得清楚的话,点个赞,只要两个就能上今日推荐,让更多人看到。如果认为我讲的不好,甚至讲错了,欢迎指正。
    本文开始,先看最简单的代码。
    function a(){
        function b(){
            x++;
            return x;
        }
        console.dir(b);
    }
    a();

    我再来说说闭包,保证初学者能看懂
    从上面可以看出,b函数中是保存a作用域中的x的,虽然从chrome中可以看出,x保存在b的closure中,
    但是我们也不会吧b叫做闭包的。因为此时b不能在a的作用域之外调用从而访问a中的变量x;

    我们先看看在a中调用b的情形
    function a(){
        var x = 0;
        function b(){
            x++;
            return x;
        }
        b();
        b();
        console.dir(b);
    }
    a();

    我再来说说闭包,保证初学者能看懂
    b中的确实保存了x的最新值。再一次声明,b不能叫做闭包,在我看来就是作用域链的问题。就像你说女人是人,是正确的。如果你把女人当人的定义来说。我就不同意了。
    作用域链能解释明白的事情,就没必要发明闭包这个概念。

    作用域链是产生闭包这个现象的核心条件之一,还差另一个重要的因素,才是我们说的闭包现象。那就是你这个b函数必须在a的作用域之外调用才行。
    怎么能在a的作用域之外调用b呢,两个办法。1.把b做为a的返回值结构的一部分。2.把b绑定dom的事件上。
    对于第一种,a能返回b,运行完a之后,保存a的返回结果,自然拿到b函数,然后再调用b,这样确实是在a的作用域之外调用b了。
    至于第二种,把b绑定dom的click事件上,我们点击dom触发b运行,也可以说在a的作用域之外,调用了b。
    多说一句,js中为啥有闭包现象,函数能当参数传,能当返回值,这才是核心原因,也是js这么屌的原因。

    这里主要来说说第一种情况
    function a(){
        var x = 0;
        function b(){
            x++;
            return x;
        }
        return b;
    }
    var c =a();
    c();
    c();
    console.dir(c);

    我再来说说闭包,保证初学者能看懂
    从打印来看c正是a中的b,c运行两次,相当在a中运行了b两次。

    而初学者,之所以容易弄不明白,总觉得运行两次c,认为里面的x仍始终是1;
    原因很简单,c()这么调用不是运行a,实际是运行b,而a呢,你始终运行了一次。如代码中var c = a()这句话。
    初学者之所以觉得x始终是1,其实像如下代码调用,才是你错误理解的方式
    function a(){
        var x = 0;
        function b(){
            x++;
            return x;
        }
        return b;
    }
    var c =a();
    c();
    var d =a();
    d();
    console.dir(c);
    console.dir(d);

    我再来说说闭包,保证初学者能看懂
    c和d其实都是b,注意这里两个b不是同一个b,是长的一模一样的双胞胎,因为a运行了两次,因而是两个。建议你研究研究,值类型和引用类型的区别。
    至于绑定dom,自己敲敲代码吧。

    c和d其实都是b,注意这里两个b不是同一个b,是长的一模一样的双胞胎,因为a运行了两次,因而是两个。建议你研究研究,值类型和引用类型的区别。
    至于绑定dom,自己敲敲代码吧。
    本文完。
    <script>
      var a =function(){
      var x =0;
           function f(){
              alert(++x);
          }
          f();
          f();
          try{
              return f
          }
          finally{
              f();
              f();
          }
      }
    var b =a();//返回里面的f
    b();
    b();

    //用于对比
    function g(){
    alert(++x);
    }
    console.dir(b);
    console.dir(g);
    </script>

    我也来说说闭包,续例
    finally可以忽略,只是演示一下,返回完以后运行的情况。其他不多说了,此时无声胜有声。在来一个绑定到dom上闭包情形
    <section>
        <button id="btn1">按钮1</button>
        <button id="btn2">按钮2</button>
    </section>
    <script>
    var c = function(){
        var x =3;
        var b1=document.getElementById('btn1');
        b1.onclick = function(){alert(x)};
        console.dir(b1.onclick);
    }
    c();
    var d = function(){
        var x =3;
        var b2=document.getElementById('btn2');
        b2.onclick =function(){alert("没有用任何上层变量")};
        console.dir(b2.onclick);
    }
    d();
    </script>

    我也来说说闭包,续例
    如果c和d合并一个函数,b2.onclick也保存了变量3.不知是chrome浏览器特有?没有拿其他浏览器测试。反正函数里既然没有使用到变量,浏览器做不做成闭包,缓不缓存局部变量。对于我们使用者来说,没啥影响。这里就不上代码和图了

    注意:摘抄于https://www.qdfuns.com/article/17398/68357db148a3aea1b7ac9d7ae071fc2d.html

  • 相关阅读:
    js 类型转换学习
    Prototypes in Javascript 收集.__proto__
    不想说作用域scope,因为是scopeTree,
    在家学习 利器 记录每日点滴
    图片切换特效的分析和学习
    js 无缝滚动效果学习
    MySQL 在高并发下的 订单撮合 系统使用 共享锁 与 排他锁 保证数据一致性
    (二)区块链的共识算法:PoS 及其 例子 代码 实现
    以太坊: ETH 发送交易 sendRawTransaction 方法数据的签名 和 验证过程
    Golang 的 协程调度机制 与 GOMAXPROCS 性能调优
  • 原文地址:https://www.cnblogs.com/Strong-stone/p/10649768.html
Copyright © 2020-2023  润新知