一看就懂的闭包讲解

概述:

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时,同时自动生成闭包。
说白了,就是有函数的地方,就存在closure,无论你是否看得见。

特点:

1.让外部访问函数内部变量成为可能;

2.局部变量会常驻在内存中;

3.可以避免使用全局变量,防止全局变量污染;

4.会造成内存泄漏(有一块内存空间被长期占用,而不被释放)

案例:

经典案例:
要求:点击当前li弹出对应内容

  <ul>
        <li>0</li>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
    </ul>
    <script>
        var lis = document.getElementsByTagName("li");
        for(var i = 0;i < lis.length;i++){
                lis[i].onclick = function(){
                    console.log(i)
                }
        }
    </script>

解析:
for循环是同步加载,点击事件是异步加载,异步加载是等同步加载完成后开始,所以当i=10的时候,点击事件开始加载执行 ,生成自己的AO,但自己的AO里没有i, 所以根据作用域链,往下找,从GO中取值,所以输出一直是10

解决方案:

 <script>
        var lis = document.getElementsByTagName("li");
        for(var i = 0;i < lis.length;i++){
            (function(i){
                lis[i].onclick = function(){
                    console.log(i)
                }
            })(i)
            
        }
    </script>

解析:在函数内部加个闭包,一个立即执行函数,每次点击,都会生成一个自己的AO,里面有i,不用去GO里取值,所以点击当前li出来对应的值

案例1:

function makeFunc() {
    var name = "chrome";
    function displayName() {    
        alert(name);
    }
    return displayName;       //注意这里
}
var myFunc = makeFunc();
myFunc();

解析:
内部函数 displayName() 在执行前,从外部函数返回。
第一眼看上去,也许不能直观地看出这段代码能够正常运行。
在一些编程语言中,一个函数中的局部变量仅存在于此函数的执行期间。
一旦 makeFunc() 执行完毕,你可能会认为 name 变量将不能再被访问。
然而,因为代码仍按预期运行,所以在 JavaScript 中情况显然与此不同。
原因在于,JavaScript中的函数会形成了闭包。
闭包是由函数以及声明该函数的词法环境组合而成的。
该环境包含了这个闭包创建时作用域内的任何局部变量。在本例子中,myFunc 是执行 makeFunc 时创建的 displayName 函数实例的引用。displayName 的实例维持了一个对它的词法环境(变量 name 存在于其中)的引用。因此,当 myFunc 被调用时,变量 name 仍然可用,其值 chrome就被传递到alert中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值