• javascript闭包浅析


    何为闭包;

    闭包跟作用域相关的,ECMAScript 允许使用内部函数,即函数定义和函数表达式位于另一个函数的函数体内。内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

    确实有点晕看个例子吧

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    </head>
    <style>
    li{
    height:30px;
    background: red;
    margin:10px;
    }
    </style>
    <body>
    <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    </ul>
    </body>
    <script>
    var lis = document.getElementsByTagName('li')
    for (var i = 0; i <= lis.length; i++){
    lis[i].onclick = function(num){
    return function(){
    alert(num);
    }
    }(i);
    }
    </script>
    </html>

    上面的例子,要给li[i]绑定点击事件,点击的时候弹出i值(i值即索引值,也就是当前是第几个li的意思啦)。如果上面没有使用闭包函数,而是直接写成(只写了js代码):

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

    此时弹出的i值变成i的最大值。原因:JS在函数执行之前的预编译期就把i值给循环一遍了,也就是i值已经不是我们过去认识的i值了。所以我们就通过闭包函数,把每一步循环的i值给保存一下,传递进去内部函数去执行新的语句。
    但是有一点必须要注意的是:闭包使函数作用域处于持续被引用的状态,不能够自动释放。只能手动清除,或者只能在浏览器窗口被关闭时才会清除占用空间,因此对于内存有一定的损耗,不推荐经常使用。
     
    闭包应用实例(tab切换效果):

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    </head>
    <style>
    *{
    margin:0;
    padding:0;
    }
    ul{
    margin:0;
    list-style: none;
    }
    #tit li{
    float:left;
    width:90px;
    height:40px;
    }
    .tit{
    background: red;
    }
    .select{
    background:gray;
    }
    #con div{
    width:270px;
    line-height:300px;
    border:1px solid red;
    font-size:50px;
    color:red;
    text-align:center;

    }
    .con{
    display:none;
    }
    .show{
    display:block;
    }
    </style>
    <body>
    <ul id="tit">
    <li class="tit select">1</li>
    <li class="tit">2</li>
    <li class="tit">3</li>
    </ul>
    <div id="con">
    <div class="con show">1</div>
    <div class="con">2</div>
    <div class="con">3</div>
    </div>
    </body>
    <script>
    var tits = document.getElementById('tit').getElementsByTagName('li'),
    cons = document.getElementById('con').getElementsByTagName('div');

    for (var i = 0, len = tits.length; i < len; i++){
    tits[i].onclick = function(i){
    // 利用闭包函数去实现i值的传递
    return function(){
    // 进行for循环,初始化类名
    for (var j = 0,len = cons.length; j < len; j++){
    tits[j].className = 'tit';
    cons[j].className = 'con';
    }
    tits[i].className = 'select';
    cons[i].className = 'show';
    }
    }(i);
    }
    </script>
    </html>

     

  • 相关阅读:
    关于tomcat内存检查的错误
    linux fedora19默认没有最大化和最小化按钮解决
    顺序栈
    在NET平台下,操作EXCEL
    【Android】状态栏通知Notification、NotificationManager详解
    Android之BroadcastReceiver
    Android之Broadcast
    Android 之Service
    我的常用网站收集
    arduino
  • 原文地址:https://www.cnblogs.com/hr2014/p/3807655.html
Copyright © 2020-2023  润新知