函数闭包问题的学习

来源:互联网 发布:图像扫描列数据 编辑:程序博客网 时间:2024/05/28 23:23

函数闭包的应用是用来解决异步问题的

<body><ul id="myUl">    <li>111</li>    <li>222</li>    <li>333</li></ul><script>    var myUl=document.getElementById("myUl");    var myLi=myUl.getElementsByTagName("li");    for(var i=0;i<myLi.length;i++){        myLi[i].onclick=function(){            alert(i+1);        }    }

这里的alert就会报错,因为for循环里面的那个匿名函数,是个异步事件,也就是说代码,顺序执行时,不会执行这个函数,只有当触发事件产生,才会执行这个函数,而此时的循环早已结束,此时的i已经为3,而myLi中是没有类名为3的,故会 报错。此时应用闭包就可以解决问题,其实严格的说,只要是定义了一个函数,这个函数执行时就产生了闭包,闭包只是一种运行机制。

var myUl=document.getElementById("myUl");    var myLi=myUl.getElementsByTagName("li");    for(var i=0;i<myLi.length;i++){        ;(function(i){            myLi[i].onclick=function(){                alert(i+1);            }        })(i)    }
 var myUl=document.getElementById("myUl");    var myLi=myUl.getElementsByTagName("li");    for(var i=0;i<myLi.length;i++){        myLi[i].onclick=(function(i){            return function(){                alert(i+1);            }        })(i)    }

修改成上述两种方式都可以,函数在执行的时候,就会形成一个私有作用域,而这个作用域里面定义的参数,是不受外界干扰的。解决异步,即保护作用域里面的参数不受外界的干扰。
关于定时器以setTimeout为例

window.setTimeout(fn(),1000);

此时,会直接执行fn(),并将fn的返回值,加入到setTimeout的队列中,
而且setTimeout天生就是一个异步的。可看一下代码,可见 闭包是处理异步的非常好用的方法。

for(var i=0;i<myLi.length;i++){       window.setTimeout((function(i){           return function(){myLi[i].style.left=100*(i+1)+"px";           }       })(i),(i+1)*1000)    }

关于函数作用域的释放问题,一般情况下当一个函数执行完之后,这个函数所创建的作用域,将会消失,当这个函数再次执行时,会再 创建一个作用域,前后两个作用域不干扰。若这个函数中产生了闭包,且这个闭包被一个时间绑定,或者返回给了一个变量,那么这个函数创建的作用域将不会消失。

function fn(){    var i=0;    return function(){        console.log(i++);    }}var a=fn();a();a();

两次打印分别为0和1。是因为 返回的函数赋给了变量,在var a=fn()这一句中函数所创建的作用域就不会被释放。

0 0
原创粉丝点击