(Javascript) 猴子也明白 之 闭包超级入门 5 写一个闭包

比起理解什么是闭包,写一个闭包更简单

前回里,通过倒腾“函数中的函数”,竟然写出了一个闭包!

原来如此!

<script>
//Sample 5-1

function outer(){
    var x = 1;    // outer里面定义一个变量

    return function (){ //这个函数就是传说中的「闭包」
        alert(x);  // "函数中的函数"里、参照外头函数outer里定义的变量。
    };

}

var f = outer();
f();  // 表示:1。
</script>

是否是闭包,需要满足以下条件:

  • 在outer里定义了某变量
  • 在outer里写一个函数(函数中的函数)
  • 在函数中的函数里,参照刚才定义的变量

这么做有什么用?

“做出了闭包挺好,但有什么值得高兴的?”

--这是最大的疑问吧。

接下来,稍微改造一下上面的代码,执行一遍:

<script>
//Sample 5-2

function outer(){
    var x = 1;

    return function (){

        x = x + 1;
    };

}

var f =  outer();
f();  // 1
f();  // 2
f();  // 3

</script>

!!

文章开头的问题被解决了:

问题:请写一个函数 f () ,随着调用次数,输出1,2,3,…

f(); // 1
f(); // 2
f(); // 3

如何解决这一问题?

 

在上面的代码里面,第一回f ()被执行后的变量x的值(=2)并没有被清除掉,

在第二回f()被执行时,把2给alert出来后,又被加1,变成了3,

并且,变量x的值(=3)仍将继续保存下去。

 

使用闭包,就可以做出“可以保存状态的函数”。

也可以认为“闭包类似于对象”。

 

至此,100%理解闭包了。

 

接下来以jQuery为例,体验一下闭包在实际中的用处吧。

 

 

 

 

补充1 匿名函数不是必须的

上例Sample 5-2,就算不使用匿名函数,也可以有各种各样的写法。

(只是,一般闭包都与匿名函数一起出现,所以介绍了匿名函数。)

非匿名函数的闭包

// Sample 5-3

function outer(){
    var x = 1;

    function inner(){
        alert(x);
        x = x + 1;
    };

    return inner;
}

var f =  outer();
f();  // 1
f();  // 2
f();  // 3

 

PS:

匿名函数的另一个重要用途是区分命名空间,没熟悉匿名函数的童靴如果第一回看jQuery的源代码,

一定被如下的匿名函数的代码块震住了,然后感慨一下高手写的代码就是看不懂。(俺就是这样)

/*!
* jQuery JavaScript Library v1.7.2
*
http://jquery.com/
*
* Copyright 2011, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
*
http://jquery.org/license
*
* Includes Sizzle.js
*
http://sizzlejs.com/
* Copyright 2011, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Wed Mar 21 12:46:34 2012 -0700
*/

(function( window, undefined ) {

     // jQuery的源代码。中间省略M行

     /*!
      * Sizzle CSS Selector Engine
      *  Copyright 2011, The Dojo Foundation
      *  Released under the MIT, BSD, and GPL Licenses.
      *  More information:
http://sizzlejs.com/
     */

    (function(){

         // Sizzle的源代码。中间省略N行

    })
})( window );

其实以上的代码不是故作高深,而是为了自己的框架定义的变量不污染全局变量

比如经典的变量$,在很多框架(如Prototype)里都定义了这个变量,为了不互相影响引入了匿名函数。

(详情参见jQuery.noConflict

补充2 “闭包”(Closure)名字的由来

Closure再英文里有关闭的意思。

变量x,被关(closed)在outer函数的命名空间里,除了inner函数以外,谁都不能使用这个变量。(大概是这个意思吧)

posted on 2012-06-12 01:15  梓シ  阅读(358)  评论(4编辑  收藏  举报

导航