【前言】
针对之前for循环读取i值。这里记录分享下
之前文章JS中for循环出现的问题:如何给li元素绑定事件,点击每个li元素弹出对应的索引?
【主体】
(1)问题描述
如何点击某一个 li 的时候 alert 输出其index?
<ul id="test"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> </ul> window.onload = function(){ var oLis = document.getElementById("test").getElementsByTagName("li"); for(var i = 0;i < oLis.length;i ++){ oLis[i].onclick = function(){ alert(i); //每次都是4 } } }
(2)原因解析
解析:因为在for循环里面指定给oLis[i].onclick的事件处理程序,也就是onclick那个匿名函数是在for循环执行完成后(用户点击时)才被调用的。而调用时,需要对变量i求值,解析程序首先会在事件处理程序内部查找,但i没有定义,然后又到方法外部查找,此时有定义,但i的值是4(只有i大于4才会停止执行for循环),因此,就会取到该值——这正是闭包(匿名函数)要使用其外部作用域中变量的结果。而且,这也是由于匿名函数本身无法传递参数(故而无法维护自己的作用域)造成的。
其实是根据作用域链的原理,在这个函数里面的i其实引用的是最后一次i的值,为什么不是0,1,2,3,...呢?因为在你for循环的时候,你并没有执行这个函数,你这个函数是在你点击的时候才执行的,当执行这个函数的时候,它发现它自己没有这个变量i,于是向它的作用域链中查找这个变量i,因为当你单击这个box的时候已经for循环完了,所以储存在作用域链里面的i的值就是4,最后就弹出出来4了。
(3)解决方案
①匿名函数/自执行函数---将每次for循环中的变量i保存到某个地方
for(var i = 0;i < oLis.length;i ++){ (function(i){ oLis[i].onclick = function(){ alert(i); //0123 } })(i); }
解释:成功打印每个 i 的值,原理就是通过自执行函数,将变量i保存到这个自执行函数的参数中。
②自定义属性
for(var i = 0;i < oLis.length;i ++){ oLis[i].index = i; oLis[i].onclick = function(){ alert(this.index); //0123 } }
解析:将每次循环得到的i,赋值给oLis[i]对象的index属性,在通过this指向,取出点击当前对象的index的值
③闭包
for(var i=0;i<li_list.length;i++){ li_list[i].onclick = function(i){ return function(){ console.log(i) } }(i) }
④ES6为我们新增了,定义变量的关键字 let,实现块级作用域
for(let i = 0;i < oLis.length;i ++){ oLis[i].onclick = function(){ alert(i); //0123 } }
【小结】
解释:let允许声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是,它声明的变量只能是全局或者整个函数块的。
【拓展】
let的几点用法:
<1>用于声明变量,不做变量提升;
<2>在同一个作用域中,不允许重复声明同一个变量;
<3>会产生块级作用域{ };
<4>特殊注意:for循环是一个块级作用域,for后{}是一个块级作用域,for块级作用域是for{}块级作用域的父级作用域。
for(let i = 0;i < 5;i++,console.log( i )){ 0 1 2 3 4 let i = 10;console.log( i ); 10 10 10 10 10 } alert(i);//报错
循环执行了几次,就存几个块级作用域,每一个块级作用域都有一个变量 i ,但是这几个i不是同一个i 。(函数内部的变量i 与 循环变量i 不在同一个作用域,有各自单独的作用域)
.
相关推荐
此“Codesys V3510 For循环案例分享”旨在为初学者提供一个实用的学习资源,帮助他们更好地理解和掌握Codesys V3 3510版本中的For循环结构。 首先,Codesys V3是德国Software AG公司开发的一种基于IEC 61131-3标准...
While和for循环 读写文件 三种读操作比较 read()读文件 readline()读文件 readlines()读文件 While和for循环 for循环实现猜三次年纪 age = 66 count = 0 for i in range(3): guess_age = int(input('age:')) if ...
在主程序中,我们使用一个for循环读取1到15(包括1和15)的Excel文件,并将所有数据合并到一个大列表`d`中。然后,我们按照`time`字段对数据进行升序排序,以便于后续处理。最后,我们使用`json.dumps()`方法将数据...
在本例中,for循环被设计成同时更新两个变量i和j。这种设计在实际编程中并不常见,但确实展示了for循环的灵活性及其在处理复杂逻辑时的能力。 ### 二、特殊加法运算逻辑 代码中,`int i; int j;` 定义了两个整型...
' 循环读取并显示文件内容 For i = 1 To 300 Dim file Set file = fso.OpenTextFile(".\test" & i & ".txt", 1) ' 1 表示只读模式 WScript.Echo "文件 .\test" & i & ".txt 的内容:" & vbCrLf & file.ReadAll() ...
根据提供的文档信息,我们可以深入探讨FOR循环语句的翻译程序设计,特别关注LL(1)分析方法以及如何生成四元式表示的中间代码。 ### 1. 系统描述 #### 1.1 问题描述 该课程设计的目标是设计、实现并调试一个能够...
### Java打印五角星for循环知识点详解 #### 一、导入必要的类库 在Java程序开始之前,我们首先需要导入所需的类库。本例中,使用了`java.util.Scanner`来接收用户输入。 ```java import java.util.Scanner; ``` ...
这两个例子展示了如何使用For循环处理序列操作,如累加和累乘,并展示了如何在循环中读取用户输入的数据。理解并熟练运用For循环,是Pascal程序设计的基础,也是进一步学习其他高级编程概念的基石。
本案例“JinAnFenXi_matlab_数据循环读取案例”提供了一个很好的教程,教你如何在MATLAB环境中实现对多组数据的循环读取、特征提取以及频谱分析。下面我们将详细探讨这些知识点。 1. **数据循环读取**: MATLAB...
### DOS FOR循环详解 在DOS(磁盘操作系统)环境下,`FOR`循环是一个非常强大的命令工具,它能够实现对一系列文件的操作,并且能够在不支持通配符的命令中使用,极大地扩展了命令行的功能性和灵活性。下面我们将...
**详解For循环** 在编程语言中,`for`循环是一种常用的控制流结构,它用于重复执行一段代码,直到满足特定条件为止。C语言中的`for`循环尤其灵活,可以适应各种复杂的迭代需求。本文将详细介绍`for`循环的结构、...
在PHP中,循环读取本地图片并实现分页显示是一个常见的需求,特别是在处理大量图片资源时,为了提高用户体验,分页加载可以有效地减轻服务器压力,同时优化页面加载速度。下面我们将详细探讨如何实现这一功能。 ...
2.5 for循环语句 2.5.1 for循环语句结构 `for`循环的基本语法如下: ```python for 循环变量 in range(start, stop, step): body(1) ``` - `start`(可选):循环开始的值,默认为0。 - `stop`:循环结束的值,不...
我们可以用一个for循环来实现: ```c #include int main() { int i, numerator = 2, denominator = 1, current_numerator, current_denominator; long long total_sum = 0; for(i = 0; i ; i++) { total_sum ...
分享者:萌神哆啦A梦,来自原文地址 一般情况下,小程序的utils这个文件夹下,我们可以把本地的数据写进去,封装成.js文件,提供对外暴露的接口,然后读取本地数据。...for (let i = 0; i < mt_
在第二段代码中,通过两个嵌套的For循环遍历1到1000的所有数,内部循环用于找到每个数的因子并累加,如果最终`i`等于`sum`,那么`i`就是一个完数。 4. **鸡兔同笼问题的解决方案** 鸡兔同笼问题是经典的数学问题,...
一个简单的方法是使用两个嵌套的for循环: ```python width, height = img.size for i in range(height): for j in range(width): pixel = img.getpixel((j, i)) # 可以在这里处理每个像素值 ``` 5. **保存...
循环在`i`小于5时进行,每次迭代读取一个输入值`m`并累加到`sum`中,然后`i`增加1。当`i`达到5时,循环结束,输出累加和。 确保循环是可终止的关键在于**循环控制条件**。在上述例子中,`i是控制条件,随着循环的...
for (int i = 0; i ; i++) { File readfile = new File(filepath + "\\" + filelist[i]); if (!readfile.isDirectory()) { System.out.println("path=" + readfile.getPath()); System.out.println("absolute ...