javascript闭包的应用

原创 2015年07月09日 10:31:41

我印象中,javascript的闭包属于进阶的范畴,无非是用来在面试中装装逼而已。你看我身边的一个小伙子,有一天我装逼地问他什么是javascript的闭包,他居然连听都没听说过。但他做起前端的东西来很快,就像我见过的其他小伙子一样。

这说明,知不知道闭包,似乎无关重要。

但是,这几天写了一些前端代码,觉得还是应该要了解这个东西。

所谓的闭包,按我的理解,就是一个javascript函数(父函数)里面有子函数,然后外界可以通过这个子函数来访问到父函数里面的变量。闭包的作用在于保护这些父函数里的变量,使得这些变量在父函数运行期结束后,继续存活,免遭javascript垃圾回收机制所回收。

怎么理解呢?举例说明。

比如说,我们在页面上输出一堆列表项,每个列表项都有一个onclick事件:

<ul>
<li id="li1" onclick="hi(1)">我是1</li>
<li id="li2" onclick="hi(2)">我是2</li>
...
</ul>

我们会发现,列表项存在着许多重复代码,造成页面代码很多。如果我们不预先给每个

  • 设置事件,而是在页面加载完毕以后,再给它们绑定onclick事件,这样页面就简洁许多,减少带宽的消耗。
  • 那么,如何绑定事件呢?假如我们这样写:

    function hi(number){
        alert("我是 " + number + " !");
    }
    $(function(){
        for(var i = 1;i <= 100; i++){
            $("#li" + i).bind("click",function(){
                hi(i);
            });
        }
    });

    那么最终,点击每个列表项,都会显示 “我是 100 !”。原因是循环结束后,i是100。

    如果换成这样子:

    function hi(number){
        return function(){//子函数,闭包机制将传入的number存储起来
            alert("我是 " + number + " !");
        };
    }
    $(function(){
        for(var i = 1;i <= 100; i++){
            $("#li" + i).bind("click",hi(i));
        }
    });

    那么就可以得到我们想要的结果。原因是,函数hi(number)中,建立了闭包,在事件绑定的时候,将传过来的i储存起来了。

    要理解上述语句,有必要对事件绑定这里做一些说明:

    $("#li" + i).bind("click",函数定义);

    意思是,绑定给元素事件的,是函数定义,而不是一个函数运行语句!一定要清楚这一点。比如说,function hi(numbert){…}是函数定义,hi(i)就是一个函数运行语句。

    我们对代码稍加修改,对比来看一下:

    function hi(number){//函数体内是普通的执行语句
        alert("我是急性子 " + number + " !");
    }
    function hi_bb(number){//函数体内返回一个子函数实例
        return function(){//子函数,闭包
            alert("我是 " + number + " !");
        };
    }
    $(function(){
        for(var i = 1;i < 3; i++){
            //此时hi执行,一次性弹出信息,绑定失败
            $("#li" + i).bind("click",hi(i));
            //此时hi_bb执行,返回了一个函数定义,绑定成功
            $("#li" + i).bind("click",hi_bb(i));
        }
    });

    在事件绑定的时候,函数hi、hi_bb都执行了。hi里面是普通的执行语句,呼啦啦的一下执行完毕,列表项未能绑定事件;而hi_bb执行后,返回的是函数定义,因此列表项事件绑定成功。

    让我们再回顾一下闭包的作用:保护父函数里的变量,使得这些变量在父函数运行期结束后,继续存活,免遭javascript垃圾回收机制所回收。 本文例子中,事件绑定之时,hi_bb执行,i作为参数传入。本来循环语句、页面onload函数结束,i就应该不存在了。但因为hi_bb里有闭包,每一个i的值都保存了下来,在以后的点击事件中,发挥出应有的作用。

    这些话好像有些勉强和装逼,我也是在体会中。如果是面向对象语言,这很好理解,对象构造自同一个类,而对象里的属性、变量的值却是不同的。把参数通过构造函数、成员方法,或者属性设置传给对象的属性或成员变量以后,对象就会将它们保存下来。javascript不是面向对象,没有类,只有函数。也许闭包就是它的一种面向对象的模拟。我是这么理解的。

    我以前也总结过闭包,现在又写了一篇,感觉又加深了一点理解:
    http://blog.csdn.net/leftfist/article/details/41868659

    可以在网站 http://jsfiddle.net/ 上运行一下这些代码,加以印证、对照。

    版权声明:本文为博主原屙文章,喜欢你就担走。

    相关文章推荐

    Javascript 理解 js闭包 应用

    一、变量的作用域要理解闭包,首先必须理解Javascript特殊的变量作用域。变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。J...
    • vx_list
    • vx_list
    • 2016年05月21日 20:17
    • 239

    JavaScript高级之闭包的概念及其应用

    主要内容: 什么是闭包闭包使用的一般模式闭包都能做些什么 本文是我的JavaScript高级这个系列中的第二篇文章. 在这个系列中,我计划分析说明 一下JavaScript中的一些常用的而又神...

    javaScript中闭包函数与this对象的应用

    Html study //闭包中关于this的一个例子 var name = '5349691'; var person = { name : 'DarkRake', w...

    javascript的闭包理解及应用注意

    什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。 相信很少有人能直接看懂这句话,因为他描述的太学术。其实这句...

    闭包的概念 形式以及在javascript,python,Ruby等语言中的应用

    什么是闭包? 闭包并不是什么新奇的概念,它早在高级语言开始发展的年代就产生了。闭包(Closure)是词法闭包(Lexical Closure)的简称。对闭包的具体定义有很多种说法,这些说法大体可以...

    javascript 执行顺序和闭包典型应用

    // 定义 ArrayList 类型 function ArrayList(array) { this._arr = typeof(array)=="string" ? array...

    Javascript中的闭包及应用

    闭包是JavaScript比较有意思的特性,也是比较难搞懂的一个概念。一个比较典型的例子就是打印循环计数—— 首先我们写一个小循环,直接打印循环变量ifunction testA() { f...
    • ucxiii
    • ucxiii
    • 2017年02月07日 00:23
    • 143

    关于JavaScript闭包的个人思考与应用

    一、闭包的概念 先说一下百度百科的解释——“闭包是可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包”...

    javascript闭包应用

    感谢《JavaScript王者归来》作者月影,之前对闭包一点都不懂,看过他的书后,终于懂一点了。以下的例子是创建一个集合,这个集合可以指定数据类型,也可以不指定。另外一个each方法很有意思。/** ...
    • yyb_gz
    • yyb_gz
    • 2011年04月17日 11:11
    • 231

    Javascript 闭包完整解释

    • 2012年11月20日 15:30
    • 100KB
    • 下载
    内容举报
    返回顶部
    收藏助手
    不良信息举报
    您举报文章:javascript闭包的应用
    举报原因:
    原因补充:

    (最多只允许输入30个字)