闭包

来源:互联网 发布:win8.1装ubuntu双系统 编辑:程序博客网 时间:2024/05/22 02:02

最近看到这样一道题:为什么点击所有的段落p输出都是4,而不是alert出对应的0,1,2,3,应该如何解决?

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title></head><body><p>我是p0</p><p>我是p1</p><p>我是p2</p><p>我是p3</p><script type="text/javascript">    function init(){        var pAry=document.getElementsByTagName("p");        for(var i=0;i<pAry.length;i++){            pAry.onclick= function () {                alert(i);            }        }    }    init();</script></body></html>

原因是由于JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元素添加点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i (如0,1,2,3,4),而是循环后最后 i 的值5.或者说循环时响应函数内并未能保存对应的值 i ,而是最后一次i++的值5. 

这里介绍两种解决方法:

方法一:将每次循环的i添加到pAry的属性i中

function init(){        var pAry=document.getElementsByTagName("p");        for(var i=0;i<pAry.length;i++){            pAry[i].i=i;            pAry[i].onclick= function () {                alert(this.i);            }        }}init();
方法二:在函数中创建一个闭包,将每次循环的i传入闭包中输出

function init(){        var pAry=document.getElementsByTagName("p");        for(var i=0;i<pAry.length;i++){            (function (i) {                pAry[i].onclick= function () {                    alert(i);                }            })(i);        }}init();

闭包的概念:

有权访问另一个函数作用域内的变量的函数叫做闭包。闭包有以下几个作用:

(1)匿名自执行函数。匿名自执行函数是一个闭包,函数执行完后会立刻释放资源,不污染全局对象

(2)结果缓存。闭包可以保留函数内部的值,当第二次调用的时候就会从缓存中读取该对象

(3)封装

(4)实现类和继承