首先 我们看一段代码  可以 猜测一下运行结果:

<body>
        <div>
                <a href= "#">Click Me!</a>
                <a href= "#">Click Me!</a>
                <a href= "#">Click Me!</a>
        </div>
        <script type = "text/javascript">
                 function main(links) {
                         for ( var i = 0; i < links.length; i++) {
                                links[i].onclick = function () {
                                        alert(i + 1);
                                }
                        }
                };
                main(document.getElementsByTagName( "a"));
        </script>

</body>


可能我们会认为应该依次弹出 1 2 3, 当我们运行这段jsp 代码发现。。其实弹出的是:4 4 4;

至于为什么会出现这种情况 就是下面的原因了-

闭包的概念

这里,我们可以看一下闭包的概念了。来自 Wiki 的说明是这样的

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

1. 诡异的闭包
javascript 中有一个特殊的特性 - 闭包,对于 .NET 程序员来说,比较熟悉的是面向对象的程序设计 OOP, 而来自函数式语言的闭包则显得比较诡异,许多程序员对它敬而远之。

对于闭包我们还是要从函数式语言的特点说起。

不知道你有没有发现,在 javascript 中没有 public ,private 之类的关键字,也没有 class ,虽然也存在对象一说,但是对象的地位远远没有在 C# 中是一等公民,在 js 中,没有对象你也可以一样写程序。它只是一种数据的表示形式而已,可有也可无。

2. 闭包何来?

如何在 javascript 实现数据的保护呢?闭包就是实现它的利器,这需要我们放下普通的对象,理解一下 javascript 的工作原理。

在 javascript 中,可以在函数中定义新的函数,这种嵌套函数还可以作为函数的返回值,被外部的变量所引用。在普通的程序设计语言中,比如 C 中,虽然也存在函数指针的概念,但是,所谓的函数指针仅仅是一段代码的地址而已,而 javascript 中返回的函数引用,则不限于此。

在 C 语言中,在函数运行的时候,局部变量是保存在堆栈中的,函数执行完毕,系统所做的是弹出堆栈。

实际上,在 javascript 中,函数每次执行的时候,注意是运行时,系统会同时创建一个此次函数运行的环境对象,而此次运行期间的局部变量则关联在这个环境对象上,在普通不返回函数 的普通函数中,函数执行完毕,则环境对象也一起释放。而如果函数返回了定义在外部函数中的嵌套函数,那么,这个环境对象将不会释放,也就是说,这个时候, 返回了一个看得见的函数对象,还附带了一个看不见的暗物质 - 外部函数的环境对象。


以上便是原因了。。。没错 就是它--JSP 的闭包!
原文链接:http://www.cnblogs.com/haogj/archive/2012/11/28/2793535.html