JS闭包经典实例详解
作者:huansky 发布时间:2024-05-09 10:20:27
本文实例讲述了JS闭包。分享给大家供大家参考,具体如下:
之前花了很多时间看书上对闭包的介绍,也看了很多人的写的关于闭包的博客,然后我就以为自己懂了。
结果,下午在一个QQ群里,有人问了这道经典的闭包问题,如下图:
我告诉他去看书上的闭包介绍。告诉他之后,我想我自己要不也写一下,反正花不了多少时间,结果花了好久怎么写也不对..............
后来看了看书上的,然后自己总结了下,觉得这次应该懂了。下次还不理解我就可以去跳楼了............
-----------------------------------分割线-----------------------------------分割线--------------------------
首先我们来了解几个概念:
立即执行函数:形如 (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


猜你喜欢
- Pycharm运行程序时,控制台输出PyDev console:starting1、问题:写好程序后,点击Run运行,控制台如下图所示提示P
- 函数可以参考:<% '注册论坛用户,参数说明 'username 用户登录名称 
- 本文实例讲述了Python实现的爬虫刷回复功能。分享给大家供大家参考,具体如下:最近闲的无聊,就想着去看看爬虫,顺着爬虫顺利的做到了模拟登录
- 关于django models中添加字段的一个小节,记录下django的models中已经写好了字段,可是后面我又想在添加一些字段,于是就在
- 本文实例讲述了C#使用Socket快速判断数据库连接是否正常的方法。分享给大家供大家参考。具体分析如下:大家在做项目的时候,一般都是和数据库
- 在做Django项目的过程中, 无法进入pycharm提供的Run manager.py Task交互环境出现这种问题是因为Pycharm无
- [编者注:]提起数据库,第一个想到的公司,一般都会是Oracle(即甲骨文公司)。Oracle在数据库领域一直处于领先地位。Oracle关系
- 前言django是一个容易快速上手的web框架,用它来创建内容驱动型的网站(比如独立博客)十分方便。遗憾的是,django并没有提供官方的富
- python中的二叉树模块内容:BinaryTree:非平衡二叉树 AVLTree:平衡的AVL树 RBTree:平衡的
- 如下所示:a = [1,2,3,4,5,6,7,8,9,10,11]step = 3b = [a[i:i+step] for i in ra
- 目录前言控制刻度间距控制刻度标签更简单的设置方式高级刻度标签控制总结前言我们首先来介绍坐标轴的范围,坐标轴的范围很好理解,有的时候我们产出的
- 本文实例为大家分享了python实现名片管理系统源代码,供大家参考,具体内容如下import osdef print_menu(): pri
- Pycharm创建的项目,使用了虚拟环境,对库的版本进行管理;有些项目的对第三方库的版本 要求不同,可使用虚拟环境进行管理直接想通过pip命
- 使用 filters 实现 英文字母 转大写1、template :<di
- 概述I/O操作不仅包括屏幕输入输出,还包括文件的读取与写入,Python提供了很多必要的方法和功能,进行文件及文件夹的相关操作。本文主要通过
- 从我们论坛中收集了这段HTML制作页面需要最大化、最小化时可以借鉴参考。最大化效果:<OBJECT id="max
- 1.1 闭包1、闭包概念1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了
- 前言最近在公司售前售后同事遇到一些奇怪的需求找到我,需要提供公司一些项目数据库所有表的结构信息(字段名、类型、长度、是否主键、***、备注)
- MySQL 触发器MySQL 数据库中触发器是一个特殊的存储过程,不同的是执行存储过程要使用 CALL 语句来调用,而触发器的执行不需要使用
- 1.什么是标准库(Standard Library)标准库指的是js的标准内置对象,是js这门语言本身初始时提供的在全局范围的对象2.Obj