• JavaScript 闭包


    这很6!!!

     

    计数器困境

    设想下如果你想统计一些数值,且该计数器在所有函数中都是可用的。

    你可以使用全局变量,函数设置计数器递增:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title>菜鸟教程(runoob.com)</title>
     6 </head>
     7 <body>
     8 
     9 <p>全局变量计数。</p>
    10 <button type="button" onclick="myFunction()">计数!</button>
    11 <p id="demo">0</p>
    12 <script>
    13 var counter = 0;
    14 function add() {
    15     return counter += 1;
    16 }
    17 function myFunction(){
    18     document.getElementById("demo").innerHTML = add();
    19 }
    20 </script>
    21 
    22 </body>
    23 </html>

    每次递增1!

    计数器数值在执行 add() 函数时发生变化。

    但问题来了,页面上的任何脚本都能改变计数器,即便没有调用 add() 函数。

    如果我在函数内声明计数器,如果没有调用函数将无法修改计数器的值:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title>菜鸟教程(runoob.com)</title>
     6 </head>
     7 <body>
     8 
     9 <p>局部变量计数。</p>
    10 <button type="button" onclick="myFunction()">计数!</button>
    11 <p id="demo">0</p>
    12 <script>
    13 function add() {
    14     var counter = 0;
    15     return counter += 1;
    16 }
    17 function myFunction(){
    18     document.getElementById("demo").innerHTML = add();
    19 }
    20 </script>
    21 
    22 </body>
    23 </html>

    每次都是1!

    以上代码将无法正确输出,每次我调用 add() 函数,计数器都会设置为 1。

    JavaScript 内嵌函数可以解决该问题。


    JavaScript 内嵌函数

    所有函数都能访问全局变量。  

    实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。

    JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。

    该实例中,内嵌函数 plus() 可以访问父函数的 counter 变量:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title>菜鸟教程(runoob.com)</title>
     6 </head>
     7 <body>
     8 
     9 <p>局部变量计数。</p>
    10 <p id="demo">0</p>
    11 <script>
    12 document.getElementById("demo").innerHTML = add();
    13 function add() {
    14     var counter = 0;
    15     function plus() {counter += 1;}
    16     plus();    
    17     return counter; 
    18 }
    19 </script>
    20 
    21 </body>
    22 </html>

    结果是1!

    如果我们能在外部访问 plus() 函数,这样就能解决计数器的困境。

    我们同样需要确保 counter = 0 只执行一次。

    我们需要闭包。


    JavaScript 闭包

    还记得函数自我调用吗?该函数会做什么?

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8">
     5 <title>菜鸟教程(runoob.com)</title>
     6 </head>
     7 <body>
     8 
     9 <p>局部变量计数。</p>
    10 <button type="button" onclick="myFunction()">计数!</button>
    11 <p id="demo">0</p>
    12 <script>
    13 var add = (function () {
    14     var counter = 0;
    15     return function () {return counter += 1;}
    16 })();
    17 function myFunction(){
    18     document.getElementById("demo").innerHTML = add();
    19 }
    20 </script>
    21 
    22 </body>
    23 </html>

    结果每次递增1!!

    解析:

    变量 add 指定了函数自我调用的返回字值。

    自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。

    add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。

    这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。

    计数器受匿名函数的作用域保护,只能通过 add 方法修改。

    Note 闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

    这写法很 6!

  • 相关阅读:
    【codeforces 411B】Multi-core Processor
    【codeforces 314C】Sereja and Subsequences
    【hdu 1890】Robotic Sort
    【图灵杯 A】谷神的赌博游戏
    【图灵杯 J】简单的变位词
    【图灵杯 F】一道简单的递推题(矩阵快速幂,乘法模板)
    【图灵杯 E也即POJ 3368】简单的RMQ
    【codeforces 496E】Distributing Parts
    【codeforces 553C】Love Triangles
    Diffie-Hellman Key Exchange – A Non-Mathematician’s Explanation
  • 原文地址:https://www.cnblogs.com/xujingyang/p/6677786.html
Copyright © 2020-2023  润新知