我一般都是说,创建一个动态存储空间,突破作用域的限制。让外部可以访问内部的变量,感觉自己答得没什么问题啊,为什么面试完没通知?
ringa_lee
函数内部变量常驻内存
函数背着自己的运行环境,像是一只蜗牛
先给出一个理解:闭包是一个函数,保存了自己创建时的环境(一般指父函数中的变量。)代码示例:
function foo(){ var a = 1; return fn(){ alert(a); } }
这里fn就是闭包。理解前半句后,来看后半句如何理解。
function foo(){ var date = new Date(); //获取当前系统时间的秒数 var a = date.getSeconds(); return function fn(){ console.log(a); } } var f = foo(); f();
在浏览器中执行后,打开控制台;控制台中的数就是当前系统时间的秒数。(刷新就会变)
这里的将闭包fn赋给了f,当f执行的时候;fn函数就会被创建,fn函数保存了此时的父环境(即a变量的值)。当再次刷新,fn函数创建的时间变了;a的值也就变了。
看到这里应该就知道什么是闭包了,以下是一个闭包的应用;没兴趣的可不看
<p> <ol id="clotest" start = "0"> <li class="item"></li> <li class="item"></li> <li class="item"></li> <li class="item"></li> </ol> </p> <script type="text/javascript"> var clotest = document.getElementById('clotest'); var nodes = clotest.getElementsByTagName('li'); for(var i = 0; i < nodes.length; i++){ nodes[i].onclick = function(){ alert(i); } } </script>
这里的需求是点击到哪个列表项;就会出现哪个值。如点击0号列表,就会弹出0。
但是当你实际点击的时候,发现弹出的值一直是4。为什么会出现这种结果呢?这里定义一组有序列表;点击到哪个列表项;就会出现哪个值。如点击0号列表,就会弹出0。 但是当你实际点击的时候,发现弹出的值一直是4。为什么会出现这种结果呢?
因为闭包保存的是它被创建时父函数中的变量啊!
计算机读取代码的时候,首先for循环;会给nodes[0]、nodes[1]等四个节点的onclick属性赋一个匿名函数。当你点击某个列表项的时候,匿名函数正式诞生;此时匿名函数的父函数i的值是4,所以当你点击任何一个列表项的时候;弹出的都是4。那怎么来解决这个问题?
我们需要在每一个node节点绑定的时候,保存下当前i的值。故我们可以定义一个handler的函数,将i作为参数传给handler函数。
var clotest = document.getElementById('clotest'); var nodes = clotest.getElementsByTagName('li'); for(var i = 0; i < nodes.length; i++){ nodes[i].onclick = handler(i); } function handler(i){ return function(){ alert(i); } }
这就是闭包的第一个作用,保存现场。
函数内部变量常驻内存
函数背着自己的运行环境,像是一只蜗牛
先给出一个理解:闭包是一个函数,保存了自己创建时的环境(一般指父函数中的变量。)
代码示例:
这里fn就是闭包。
理解前半句后,来看后半句如何理解。
在浏览器中执行后,打开控制台;控制台中的数就是当前系统时间的秒数。(刷新就会变)
这里的将闭包fn赋给了f,当f执行的时候;fn函数就会被创建,fn函数保存了此时的父环境(即a变量的值)。当再次刷新,fn函数创建的时间变了;a的值也就变了。
看到这里应该就知道什么是闭包了,以下是一个闭包的应用;没兴趣的可不看
这里的需求是点击到哪个列表项;就会出现哪个值。如点击0号列表,就会弹出0。
但是当你实际点击的时候,发现弹出的值一直是4。为什么会出现这种结果呢?
这里定义一组有序列表;点击到哪个列表项;就会出现哪个值。如点击0号列表,就会弹出0。
但是当你实际点击的时候,发现弹出的值一直是4。为什么会出现这种结果呢?
因为闭包保存的是它被创建时父函数中的变量啊!
计算机读取代码的时候,首先for循环;会给nodes[0]、nodes[1]等四个节点的onclick属性赋一个匿名函数。
当你点击某个列表项的时候,匿名函数正式诞生;此时匿名函数的父函数i的值是4,所以当你点击任何一个列表项的时候;弹出的都是4。
那怎么来解决这个问题?
我们需要在每一个node节点绑定的时候,保存下当前i的值。故我们可以定义一个handler的函数,将i作为参数传给handler函数。
这就是闭包的第一个作用,保存现场。