博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js 中的闭包
阅读量:6196 次
发布时间:2019-06-21

本文共 2596 字,大约阅读时间需要 8 分钟。

闭包(closure)

        先来看一个实例,javascript代码:

[javascript]
  1.     <script type="text/javascript">  
  2.     function newLoad(){ //新建页面加载的事件   
  3.         for (var i = 1; i <=3; i++) {  
  4.                 var anchor = document.getElementById("anchor" + i); //找到每个anchor   
  5.                 anchor.onclick = function () {
    //为anchor添加单击事件   
  6.                         alert ("you clicked anchor"+i);//给出点击反应   
  7.                 }  
  8.         }  
  9. }  
  10. window.onload = newLoad; //把newload事件赋值给页面加载   
  11.     </script>  

<script type="text/javascript"> function newLoad(){ //新建页面加载的事件 for (var i = 1; i <=3; i++) { var anchor = document.getElementById("anchor" + i); //找到每个anchor anchor.onclick = function () {//为anchor添加单击事件 alert ("you clicked anchor"+i);//给出点击反应 } } } window.onload = newLoad; //把newload事件赋值给页面加载 </script>        前台代码:

[html]
  1. <body>  
  2. <a id="anchor1" href="#">anchor1</a><br/>  
  3. <a id="anchor2" href="#">anchor2</a><br/>  
  4. <a id="anchor3" href="#">anchor3</a><br/>  
  5. </body>  

<body> <a id="anchor1" href="#">anchor1</a><br/> <a id="anchor2" href="#">anchor2</a><br/> <a id="anchor3" href="#">anchor3</a><br/> </body>        运行结果:无论点击那个anchor,总会弹出anchor4,而我们根本就没有anchor4:

 

        当我们加载页面时,javascript中的newLoad函数已经运行完毕,由其中的循环可知,anchor已经赋值为4。但是由以前的编程经验来看,局部变量使用完毕就会销毁,但是anchor却没有,显然这里 JavaScript 采用了另外的方式。

        闭包在 JavaScript 其实就是一个函数,在函数运行期被创建的,当上面的 函数被执行的时候,会创建一个闭包,而这个闭包会引用newLoad 作用域中的anchor。下面就来看看 JavaScript 是如何来实现闭包的:当执行 newLoad 函数的时候, JavaScript 引擎会创建newLoad函数执行上下文的作用域链,这个作用域链包含了 newLoad执行时的活动对象,同时 JavaScript 引擎也会创建一个闭包,而闭包的作用域链也会引用 newload的活动对象,这样当 newload执行完的时候,虽然其执行上下文和活动对象都已经释放了anchor,但是闭包还是引用着 newload 的活动对象,所以点击显示的是“you clicked anchor4”。运行期如图:

闭包优化

            既然闭包出现了我们不想看到的结果,我们需要优化它。优化后的javascript(其他不变):

[javascript]
  1. <script type="text/javascript">  
  2.        function newLoad() { //新建页面加载的事件   
  3.                for (var i = 1; i <= 3; i++) {  
  4.                        var anchor = document.getElementById("anchor" + i); //找到每个anchor   
  5.                        listener(anchor,i);//listener函数   
  6.                        }  
  7.                }  
  8.            function listener(anchor, i) {  
  9.                    anchor.onclick = function () {
    //为anchor添加单击事件   
  10.                            alert("you clicked anchor" + i); //给出点击反应   
  11.                    }  
  12.           }  
  13.        window.onload = newLoad; //把newload事件赋值给页面加载   
  14. lt;/script>  

<script type="text/javascript"> function newLoad() { //新建页面加载的事件 for (var i = 1; i <= 3; i++) { var anchor = document.getElementById("anchor" + i); //找到每个anchor listener(anchor,i);//listener函数 } } function listener(anchor, i) { anchor.onclick = function () {//为anchor添加单击事件 alert("you clicked anchor" + i); //给出点击反应 } } window.onload = newLoad; //把newload事件赋值给页面加载 </script>        运行结果:提示对应的提示信息

 

        结果分析:优化后的结果是因为,我们把声明的变量和单击事件相分离。用以上解释的作用域链解释:页面加载,先执行listener函数,而listener函数需要anchor变量,在listener函数作用域链中没有,会进入下一级作用域链,即查找newLoad中的anchor,因为在listener中已经确定了哪个anchor单击对应哪个提示信息,所以只是在newload中查找对应的anchor而已,不会等循环完毕产生anchor4。

转载于:https://www.cnblogs.com/walleyekneel/archive/2012/06/29/2569989.html

你可能感兴趣的文章
[Selenium] HTML5 中的 Geolocation
查看>>
暴力(判凸四边形) FZOJ 2148 Moon Game
查看>>
线段树/树状数组 POJ 2182 Lost Cows
查看>>
最短路(Bellman_Ford) POJ 3259 Wormholes
查看>>
01背包 URAL 1073 Square Country
查看>>
poj1012
查看>>
javascript思想干货
查看>>
过滤器
查看>>
BZOJ2752:[HAOI2012]高速公路——题解
查看>>
BZOJ3530:[SDOI2014]数数——题解
查看>>
线程与进程的区别?
查看>>
NetCore入门篇:(九)Net Core项目使用Session及用Redis做分布式
查看>>
ora-01033:oracle initialization or shutdown in progress 解决方法
查看>>
Linux (Ubuntu)提示ifconfig:找不到命令
查看>>
LNMP 多用户动态进程管理虚拟主机方案
查看>>
CentOS6.8 安装FTP及添加用户
查看>>
StackPanel布局
查看>>
Python--day24--复习
查看>>
hdu 4686 矩阵乘法优化递推关系
查看>>
[转] MONGODB基本命令用
查看>>