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闭包下面的评论区看激烈的讨论(等到理解了差不多的时候,可以发表自己的意见)

原文地址:https://www.cnblogs.com/SCAU-gogocj/p/13113525.html