zoukankan      html  css  js  c++  java
  • Day3-JS-闭包

     小知识:

        1、在web页面中全局变量属于 window 对象

    一、JS内嵌函数

      === JavaScript 中,所有函数都能访问它们上一层的作用域,JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量

    引入:(在本示例中,plus函数可以访问上一级的的,也就是add这个函数里面的counter)

    function add() {
        var counter = 0;
        function plus() {counter += 1;}
        plus();    
        return counter; 
    }

    ===但是如果可以在add函数的外面也可以访问plus函数呢,并且也可以使用counter变量,需要闭包

    二、JS闭包

          ①实例

    var add = (function () {
        var counter = 0;
        return function () {return counter += 1;}
    })();
     
    add();
    add();
    add();
     
    // 计数器为 3

    在该自调用函数中,这个自调用函数只执行依次,设置counter==0,然后把里面的函数表达式给add,

    使得,add变量可以作为一个函数来使用了,并且还可以访问开始定义的counter这个变量

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

    ==因为在这个自调用函数,返回的是一个方法,把add变量变成一个函数的方法

    每次调用add() 其实都是在调用return counter += 1

    闭包会持有父方法的局部变量并且不会随父方法销毁而销毁, 所以这个counter其实就是来自于第一次function执行时创建的变量。

    一个解释闭包的demo

    5楼:

    var tmp = 2; //理论上在退出语句块后,这个变量要被释放掉的。包括内存可能被回收。但事实并非如此,会影响后面和他同名的变量
    }
    
    var add = (function () {
        //var counter = 0; //这里注释掉.其实和上面的tmp一样的道理。这里在函数自己执行完后就应该销毁了的。
        //return function () {return counter  += 1;} //这里的counter已经不是上面的counter了,是一个全局变量。有初值,受上面影响,初值为0
        return function () {return tmp += 1;} //这里tmp就是个全局变量。它是有初值的。为上面的2
    
    })();
    function myFunction(){
        document.getElementById("demo").innerHTML = add();//3
        document.getElementById("demo").innerHTML = add();//4
        document.getElementById("demo").innerHTML = add(); //5
    }
    
    </script>

    评论中,一位大佬就是通过上面的,构建全局变量的方法来实现的

    6楼:

    <button type="button" onclick="myFunction()">计数!</button>
    <p id="demo">0</p>
    <script>
    var add = new Object();
    add.count = 0;
    add.plus = function()
    {
        this.count++;
    }
    function myFunction(){
        add.plus();
        document.getElementById("demo").innerHTML = add.count;
    }
    </script>

    就是通过 new Object 新建了一个add对象,如果定义了count这个属性,和plus这个方法

    但是!!!!

    看到后面的评论就把上面的两个代码搞死了:

    var add =function () {
        var counter = 0;
        window.alert("父方法"); // 只有在 add 赋值时执行一次 
        return function () {
            window.alert("子方法");  // 每次执行 add() 都会执行
            return counter += 1;
    
        }    
        // counter 作用域在父函数中, 自然在其子函数中也能使用,但因为
        // 子函数还需要使用了count, 所以 count 不随着父函数一起释放。    
        // 利用在 function(){}() 的形式自动执行一遍父匿名函数, 赋给 add 子方法。
    }();
    
    function myFunction(){
        document.getElementById("demo").innerHTML = add();  //这里add()执行的就是子方法
    }

    具体可以到菜鸟教程JS闭包下面的评论区看激烈的讨论(等到理解了差不多的时候,可以发表自己的意见)

  • 相关阅读:
    sqlserver2005"此数据库没有有效所有者,因此无法安装数据库关系图支持对象"的解决方法
    重复表的复制操作
    重复表中连级下拉框采用数据源时,子级下拉框列表数据无法持久的问题
    SQL server2005连接与进程
    重复表操作
    XPath语法
    Request.ServerVariables 参数大全
    50个Sql语句
    Inside C++ new/delete and new[]/delete[]
    颜色空间
  • 原文地址:https://www.cnblogs.com/SCAU-gogocj/p/13113525.html
Copyright © 2011-2022 走看看