可以先看这篇JS中函数的各种叫法
JS中的闭包: 所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数), 因而这些变量也是该表达式的一部分。看不懂了把?·········其实我也看不懂!! 一直很羡慕那些给变量取名字的科学家,因为只有他们才能轻松理解那个词说的是什么······· 闭包的作用: 1) 函数外面可以访问函数内部的局部变量 2) 使变量所占的内存不被释放 根据作用域链和变量的生存期我们知道,变量只能沿着作用域链向上(即函数内可以访问函数内的变量 ,而函数外部不能访问函数内定义的局部变量)查找,反之则不可以 而局部变量在函数执行完成后就销毁了。而闭包的存在,使得这两点变的可能 闭包的原理:根据JS中的垃圾回收机制,当一个对象没有变量来引用的时候,它就将会被回收. 闭包中,外部变量引用了内部变量,使得变量保存了下来,这是我肤浅的理解,实际上不一定时这样。 我们来看几个小例子: 我们想用一个变量来统计某个方法执行的次数 例子1: <script> var count=0; //定义一个全局变量 function test(){ count++; return count; } alert(test()); //1 alert(test()); //2 alert(test()); //3 虽然这样做能实现效果,但容易污染全局变量,来考虑其他方法 </script> 例子2 <script> function test(){ var count=0; count++; return count; } alert(test()); // 1 alert(test()); // 1 alert(test());// 1 我们发现,三次都弹出1,这是因为count为局部变量的原因,每一次执行,都会从新定义并赋值为0. </script> 例子3: 使用闭包实现累加方法1: <script> function box(){ var age=100; return function(){ //返回一个匿名函数,这就产生了闭包 age++; return age; }; } var b=box(); alert(b());//101 alert(b());//102 alert(b());//103 alert(b); //funciton(){age++;return age;} ============华丽的分割线============== /* 方法2: 除了返回一个匿名函数,我们可以将匿名函数赋值给一个全局变量, 这样,全局变量引用了那个匿名函数,而匿名函数内部又使用了a变量, 所以整个函数的执行环境保留了下来,局部变量age的值就一直保留了下来 */ var c; function box(){ var age=100; c= function(){ // 包匿名函数直接赋值给一个全局变量,也产生了闭包 age++; alert(age); }; } box();//执行一次方法box,将匿名函数复制给全局变量c c();//101 c();//102 c();//103 </script> 闭包的典型应用,据说经常会出面试题。在循环中直接找到对应元素的索引 例子:给ID为ul1 的UL下的四个Li,让每个li点击时弹出自己的索引,如点击第一个li弹出0 等 常规思路:遍历li,给每个Li添加点击事件,同时弹出i var ul1=document.getElementById("ul1"); var aLi=ul1.getElementsByTagName("li"); for(var i=0;i<aLi.length;i++){ aLi[i].onclick=function(){ alert(i); }; } cosnole.log(i); // 4 整个for循环结束后,i并没有被销毁,因为他是全局的!! 看起来没有问题,执行后我们发现,无论点击那个li,都是弹出的 4 那么 4 是哪了来的呢?? 这还是变量的作用域和生存期的原因,我们知道,JS中不存在块作用域,在for循环li定义的i 其实就是全局的,当每一个li点击时,执行alert(i) ,i就会根据作用域链去查找,找到的就是那个全局的i 所以都弹出的是4.也就是说,每一个li访问到的其实是同一个i 解决办法:让每一个Li都有一个自己的i 使用闭包来解决: var ul1=document.getElementById("ul1"); var aLi=ul1.getElementsByTagName("li"); for(var i=0;i<aLi.length;i++){ //使用一个即时函数 (function(i){ aLi[i].onclick = function(){ alert(i); }; })(i); /* 也可以这样:闭包的存在,使得j保留下来了 aLi[i].onclick=(function(){ var j=i; 每一个Li都有一个自己的j return function(){ alert(j); }; })(); */ } 当然,闭包还有很多应用,这里只是举个简单的例子。 闭包的使用也会带来一些问题:比如大规模使用闭包可能导致内存泄漏等问题。 你理解闭包了吗?
转载请注明:副业 and 脱单研究所 » 详解JS中的闭包