zoukankan      html  css  js  c++  java
  • 详解javascript中的闭包

    全局变量与局部变量

    在说闭包之前先说明全局变量与局部变量

    • 全局变量:变量声明时如果不使用 var 关键字,那么它就是一个全局变量,即便它在函数内定义。
    • 局部变量:使用var关键字定义

    全局变量/局部变量的作用域:

    全局变量作用于整个程序,任何一处代码都能访问,局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。

    全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。

    第二需要知道的预备知识:javascript的作用域,请参考博客javascript基础

    变量的生命周期

    全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。

    而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用,函数一旦执行完毕,局部变量将释放。

    先看示例:计数器问题

    function add() {
        var counter = 0;
        counter += 1;
    }
    
    add();
    add();
    add();
    
    // 本意是想输出 3, 但事与愿违,输出的都是 1 !

    当我们把局部变量在换成全局变量在看计数器问题

        counter=0;
    function add() {
        counter+=1;
        console.log(counter);
    
    }
    add();
    add();
    add();//最后结果输出3,本次结果虽然符合我们的要求,但是修改全局变量对于我们程序是不友好的,因为可能在任何一处都可能使用到该全局变量
    闭包的引入与示例

    从javascript的作用域我们知道,函数的嵌套可以使得内部函数可以访问到上一层函数的变量,这样我们就可以利用函数的嵌套解决计数器问题。

    示例:

    function add() {
        var counter=0;
        function innerAdd() {
            counter+=1;
        }
        innerAdd();
        return counter
    
    }
    add();
    add();
    res=add();
    console.log(res)
    //输出1.,这是因为每次调用add函数时候都把counter进行了重新赋值为0了,如果我们让counter=0只执行一次,那么问题就得到解决了。
    javascript的闭包

    在javascript中有一类函数是自执行函数,这里我们我们将用它来解决计数器问题;

    示例:

    var add=(function() {
        var counter=0;
        return function () {
            counter+=1;
            console.log(counter )
        }
    })()
    add();
    add();
    add();
    //输出counter值为3

    示例解析:

    1. 变量 add 指定了函数自我调用的返回字值;
    2. 自我调用函数只执行一次。设置计数器为 0。并返回函数表达式;
    3. add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器;
    4. 这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能;
    5. 计数器受匿名函数的作用域保护,只能通过 add 方法修改;
    6. 闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。

    总结:

    闭包就是一个函数引用另一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会增加内存消耗。

    或者说闭包就是子函数可以使用父函数的局部变量,还有父函数的参数。

  • 相关阅读:
    ◆◆0[代码]基于动态内表的ALV
    SALV教程19-自定义按钮事件(EVENT)[added_function]
    创建list ALV tree[RS_TREE_LIST_DISPLAY]
    ◆◆0REUSE_ALV_GRID_DISPLAY_LVC-可编辑单元格
    ◆◆0SALV的一些限制和注意事项汇总
    ◆◆0SALV教程20-单元格可编辑
    REUSE_ALV_GRID_DISPLAY_LVC-双击事件’&IC1′
    ◆◆0REUSE_ALV_GRID_DISPLAY_LVC-行选择功能
    [代码]REUSE_ALV_GRID_DISPLAY_LVC-代码模板
    ◆◆0[问题解决]ALV可输入状态下输入金额/数量字段小数位数提前的问题
  • 原文地址:https://www.cnblogs.com/wdliu/p/7483304.html
Copyright © 2011-2022 走看看