一看就懂的闭包讲解

概述:

函数和对其周围状态(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中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值