JS闭包经典实例详解

作者:huansky 时间:2024-05-09 10:20:27 

本文实例讲述了JS闭包。分享给大家供大家参考,具体如下:

之前花了很多时间看书上对闭包的介绍,也看了很多人的写的关于闭包的博客,然后我就以为自己懂了。

结果,下午在一个QQ群里,有人问了这道经典的闭包问题,如下图:

JS闭包经典实例详解

我告诉他去看书上的闭包介绍。告诉他之后,我想我自己要不也写一下,反正花不了多少时间,结果花了好久怎么写也不对..............

后来看了看书上的,然后自己总结了下,觉得这次应该懂了。下次还不理解我就可以去跳楼了............

-----------------------------------分割线-----------------------------------分割线--------------------------

首先我们来了解几个概念:

立即执行函数:形如 (function(){})();的一类函数;

闭包:闭包是指有权访问另一函数作用域中的变量的函数。

作用域链:当代码执行的时候,会创建变量对象的一个作用域链....(具体百度)

我们再来看这个问题,我重新写了一个,源码如下:


<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>闭包经典例子详解——huansky</title>
</head>
<body>
 <div id="ttt">
   <p >000000000000000000</p>
     <br>
   <p >111111111111111111</p>
   <br>
   <p >222222222222222222</p>
 </div>
</body>
<script>
var dom=document.getElementsByTagName("p");
for(var i=0;i<dom.length;i++){
   dom[i].onclick=function(){
     console.log(i);//3
   };
}
</script>
</html>

首先,代码中的匿名函数没有变量 i,所以它必须向上查找,在全局环境中找到了 i。

for循环运行后,全局变量中的 i 变成了3。此时当你点击文字的时候,会调用其绑定的函数,而该函数运行的时候,发现自己没有 i,就会取得全局环境中的 i。

所以,最后的结果是,不管你点击那段文字,最后结果都是3。

PS:感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码,看看运行效果。

那怎么办呢?你可以用立即执行函数,看代码:


for(var i=0;i<dom.length;i++){
   dom[i].onclick=function(i){
     return function( ){
     console.log(i);
     };
   }(i);
}

我们把参数 i 作为传给立即执行函数,这样,i 的值就传给了立即执行函数的局部变量 i 了。立即执行函数会直接执行,但是其活动不会销毁,因为里面有个匿名函数。执行后局部变量 i 与全局变量 i 联系就切断了,也就是执行的时候,传进去的变量 i 是多少,立即执行函数的局部变量 i  就是多少,并且该局部变量 i 仍然没有消失,因为匿名函数的存在。

这时候,return中的匿名函数的作用域链中会有两个变量 i。当点击文本的时候,它向上搜索 i 的时候,它找到立即执行函数的局部变量 i ,就停止向上查找了,因此最后的结果就不会是全局变量 i 的值3了。

有一个方法可以检验你们有没有真的理解上面所说的,看上面的变体,代码:


for(var i=0;i<dom.length;i++){
   dom[i].onclick=function(t){
     return function( ){
     console.log(t);//1
     console.log(i);//3
     };
   }(i);
}

其实return中的匿名函数中的 t 就是立即执行函数的局部变量 i,而 i 就是 指全局变量 i,因为立即执行函数中没有变量i,只能继续向上搜索,然后就找到全局变量的 i 了。

如果看到这里,你还没有理解,有两个原因:一个原因是我表达的不够好,另一个原因是你没有完全理解前面提到的这些概念,还要继续看书。

希望本文所述对大家JavaScript程序设计有所帮助。

来源:https://www.cnblogs.com/huansky/p/5450767.html

标签:JS,闭包
0
投稿

猜你喜欢

  • PHP json_encode中文乱码解决方法

    2023-07-12 20:20:14
  • 强制SQL Server执行计划使用并行提升在复杂查询语句下的性能

    2024-01-14 16:30:38
  • Python入门学习之字符串与比较运算符

    2023-10-14 22:09:40
  • MSSQL数据类型

    2008-08-03 17:21:00
  • PHP中使用Memache作为进程锁的操作类分享

    2023-11-22 18:10:02
  • Go语言标准输入输出库的基本使用教程

    2023-08-25 19:44:11
  • 用Python写冒泡排序代码

    2022-09-14 23:55:11
  • Python面向对象之接口、抽象类与多态详解

    2021-10-24 10:26:48
  • python使用Tesseract库识别验证

    2023-05-06 12:31:51
  • Python2.x版本中基本的中文编码问题解决

    2021-01-06 14:02:16
  • Python实现图片与视频互转代码实战(亲测有效)

    2021-05-30 17:21:03
  • My Sql 1067错误与编码问题的解决方案

    2024-01-19 12:53:53
  • python多维列表总是只转为一维数组问题解决

    2022-12-27 00:25:21
  • Python数据分析之NumPy常用函数使用详解

    2021-09-29 06:17:33
  • vue 使用vant插件做tabs切换和无限加载功能的实现

    2024-04-10 13:49:34
  • 一个比较实用的大数据量分页存储过程

    2024-01-13 16:11:29
  • Python通过两个dataframe用for循环求笛卡尔积

    2023-11-02 04:32:24
  • PHP中__LINE__,__FILE__,__DIR__等常用魔术常量实例讲解

    2023-06-13 23:42:32
  • Go 微服务开发框架DMicro设计思路详解

    2024-05-22 17:48:31
  • Django 报错:Broken pipe from ('127.0.0.1', 58924)的解决

    2021-03-27 21:12:09
  • asp之家 网络编程 m.aspxhome.com