六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 55|回复: 0

JavaScript中级笔记(4)

[复制链接]

升级  81.33%

44

主题

44

主题

44

主题

秀才

Rank: 2

积分
172
 楼主| 发表于 2013-2-7 17:57:44 | 显示全部楼层 |阅读模式
前面已经讲解了 引用,函数重载,作用域和上下文,接下来,讲解JavaScript中另一个重要的知识——闭包。
   
    5,闭包

   
    闭包意味着内层的函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经终止。
    让我们先来看一个闭包的例子。

    <script type="text/javascript">    function add(num){        return function(toAdd){            return num+toAdd; //代码①        }    }    var addFive = add(5); //此时addFive为function(toAdd){return num+toAdd;}    var count = addFive(3); //此时count为 num+toAdd    alert(count);//8    </script>

    代码①是处于函数内层,不过它可以使用外层的变量num。

    闭合还能解决另一个常见的Js问题,全局变量的影响。
    通过自动执行匿名函数组合闭包,便可把原本属于全局的变量隐藏起来。看下面的例子:

    <script type="text/javascript">    (function(){        var msg = "Hello";        window.onunload  = function(){            alert(msg);//输出Hello        }    })()    //alert(msg);//出现未定义    </script>

    在使用setTimeout时,我们经常也用上了闭包。

    <html>    <head>    <title>demo</title>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <script type="text/javascript">    window.onload = function(){        var obj = document.getElementById("abc");        obj.style.border = "1px solid #000";        setTimeout(function(){            obj.style.color = "red";        },1000)                function DeAlert(msg , time){            setTimeout( function(){                alert(msg);             },time)        }        DeAlert("hello",2000);    }    </script>    </head>    <body>    <div id="abc">CssRain</div>    </body>    </html>

    以这种方式使用setTimeout(),可以避免一些问题。

    当然使用闭包 也会带来一些问题。如下代码所示:

    <html xmlns="http://www.w3.org/1999/xhtml">    <head>    <title>demo</title>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <script type="text/javascript">    window.onload = function(){        var ul = document.getElementById("abc");        var li = document.getElementsByTagName("li");        for(var i=0;i<li.length;i++){            li[i].onclick = function(){                alert("你单击的是第"+i+"个li。");            }        }    }    </script>    </head>    <body>    <ul id="abc">        <li>AAA</li>        <li>BBB</li>        <li>CCC</li>    </ul>    </body>    </html>

    单击li弹出的序号为 3 ,并不是正确的序号,它引用的值是最后一次的赋值。
    我们可以使用下面代码来解决:

    <script type="text/javascript">    window.onload = function(){        var ul = document.getElementById("abc");        var li = document.getElementsByTagName("li");        for(var i=0;i<li.length;i++){            (function(){  //使用一个自执行的匿名函数 来激发出作用域                var b = i ;    //记住在这个作用域内的值                li[b].onclick = function(){ //使用刚才记住的值,变量b                    alert("你单击的是第"+b+"个li。");                }            })()        }    }    </script>

    通过使用闭包对作用域的控制,从而符合了我们的要求。
    上面的代码可以分解为:

    <script type="text/javascript">    window.onload = function(){        var ul = document.getElementById("abc");        var li = document.getElementsByTagName("li");        function a(){                var b = 0 ;                   li[b].onclick = function(){                    alert("你单击的是第"+b+"个li。");                }        }        function b(){                var b = 1 ;                 li[b].onclick = function(){                    alert("你单击的是第"+b+"个li。");                }        }        function c(){                var b = 2 ;                  li[b].onclick = function(){                    alert("你单击的是第"+b+"个li。");                }        }        a();        b();        c();    }    </script>

    闭包的概念不容易掌握,我也是花了大量时间和精力才理解。

    6,小结
    笔记(2),(3),(4)讲解了 JavaScript中的几个重要的内容,包括引用,函数重载,作用域,上下文对象和闭包。

    引用的关键内容:         指针,数组引用,字符串引用,区别,传值,传址。
    函数重载的关键内容:    参数的数量,参数的类型,arguments,伪数组,typeof,constructor,区别-字符串和对象。
    作用域的关键内容:       函数划分,全局作用域,全局对象,window对象的属性,局部作用域,显式声明,隐式声明。
    上下文对象的关键内容: this变量,call,apply,参数区别,数组。
    闭包的关键内容:         内层函数,外层函数,变量,setTimeout,闭包问题,最后一次的赋值,闭包和作用域。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表