for 循环中的 i 变量问题
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
}
}
}
解析:因为在for循环里面指定给oLis[i].onclick的事件处理程序,也就是onclick那个匿名函数是在for循环执行完成后(用户点击时)才被调用的。而调用时,需要对变量i求值,解析程序首先会在事件处理程序内部查找,但i没有定义,然后又到方法外部查找,此时有定义,但i的值是4(只有i大于4才会停止执行for循环),因此,就会取到该值——这正是闭包(匿名函数)要使用其外部作用域中变量的结果。而且,这也是由于匿名函数本身无法传递参数(故而无法维护自己的作用域)造成的。
2:解决办法
方法一:
window.onload = function(){
var oLis = document.getElementById("test").getElementsByTagName("li");
for(var i = 0;i < oLis.length;i ++){
(function(i){
oLis[i].onclick = function(){
alert(i); //0123
}
})(i);
}
}
解释:成功打印每个i的值,原理就是通过自执行函数,将变量i保存到这个自执行函数的参数中。
方法二:
window.onload = function(){
var oLis = document.getElementById("test").getElementsByTagName("li");
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的值。
方法三:
window.onload = function(){
var oLis = document.getElementById("test").getElementsByTagName("li");
for(var i = 0;i < oLis.length;i ++){
oLis[i].onclick = (function(e){
return function(){
alert(e); //0123
}
})(i);
}
}
解释:
3:其他
window.onload = function(){
var oLis = document.getElementById("test").getElementsByTagName("li");
for(var i = 0;i < oLis.length;i ++){
oLis[i].onclick = a();
function a(){
alert(i); /0123
}
}
}
解释:虽然这样可以打印出每次变量i的值,但是我们没有点击li的时候他已经执行完了,也就是说,这个点击事件已经可有可无了,所以我们这种方法在绑定事件中不可用。
4:ES6为我们新增了,定义变量的关键字 let
window.onload = function(){
var oLis = document.getElementById("test").getElementsByTagName("li");
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 不在同一个作用域,有各自单独的作用域)
for 循环中的 i 变量问题的更多相关文章
- 【Javascript】: for循环中定义的变量在for循环体外也有效
for循环中定义的变量在for循环体外也有效 <script> (function(){ var a = 111; for(var i=0;i<5;i++){ var carl = ...
- bash的循环中无法保存变量
在bash中,如果循环在一个子shell中运行,那么在循环中对循环外面的变量的更改将在循环退出后不可见.像下面的例子: #!/bin/sh python run.py | while read lin ...
- 11 tensorflow在tf.while_loop循环(非一般循环)中使用操纵变量该怎么做
代码(操纵全局变量) xiaojie=1 i=tf.constant(0,dtype=tf.int32) batch_len=tf.constant(10,dtype=tf.int32) loop_c ...
- (python)循环中动态产生变量
>>> for i in xrange(5): exec 'a'+str(i)+' = '+str(i)+'' >>> a0 0 >>> a1 1 ...
- js for 循环中的 变量问题。
今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...
- 关于在for循环中绑定事件打印变量i是最后一次。
其实函数引用的外部变量都是最后一次的值. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- 关于while read line 循环中变量作用域的问题
前一阵用shell写了一个从数据库中抽取数据生成.xml文件的脚本,要求是每个文件中只生成1000条数据.于是用到了while read line 作为循环. 在制作文件计数器的时候发现了一个问题,在 ...
- 【SQL】小心在循环中声明变量——浅析SQL变量作用域
本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...
- 注意for循环中变量的作用域-乾颐堂
1 2 for e in collections: pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...
随机推荐
- XHR
xhr注入 XHR 注入技术是通过XMLHttpRequest来获取javascript的.但与eval不同的是,该机制是通过创建一个script的DOM元素,然后把XMLHttpRequest的响应 ...
- 在Word2010文档中显示域代码而非域值
当Word2010文档中含有域内容时,默认情况下显示域值,这样可以使插入的域内容清晰明了.用户可以根据需要选择显示域代码或显示域值,操作步骤如下所述: 步骤/方法 第1步,打开Word2010文档窗口 ...
- 一次thinkphp框架 success跳转卡顿问题的解决
近期工作中遇到了一个奇怪的现象:thinkphp框架中一个控制器中执行success或者error跳转的时候,会卡10s甚至更久,而在其他控制器中测试却不会.于是开始着手调试,利用自定义的毫秒函数测试 ...
- java面向对象——类
一.类 类(class)是构造对象的模板或蓝图.由类构造(construct)对象的过程称为创建类的实例(instance). 用 java 编写的所有代码都位于某个类的内部.标准的Java 库提供了 ...
- 浅谈Android进阶之路
过去十年是移动互联网蓬勃发展的黄金期,相信每个人也都享受到了移动互联网红利,在此期间,移动互联网经历了曙光期.成长期.成熟期.现在来说已经进入饱和期.依然记得在 2010-2013 年期间,从事移动开 ...
- 【深度学习系列】迁移学习Transfer Learning
在前面的文章中,我们通常是拿到一个任务,譬如图像分类.识别等,搜集好数据后就开始直接用模型进行训练,但是现实情况中,由于设备的局限性.时间的紧迫性等导致我们无法从头开始训练,迭代一两百万次来收敛模型, ...
- 关键字final整理
关键字final整理 由于语境(应用环境)不同,final 关键字的含义可能会稍微产生一些差异.但它最一般的意思就是声明"这个东西不能改变".之所以要禁止改变,可能是考虑到两方面的 ...
- ng机器学习视频笔记(十六) ——从图像处理谈机器学习项目流程
ng机器学习视频笔记(十六) --从图像处理谈机器学习项目流程 (转载请附上本文链接--linhxx) 一.概述 这里简单讨论图像处理的机器学习过程,主要讨论的是机器学习的项目流程.采用的业务示例是O ...
- Eclipse使用EGit,commit之后仍显示NO HEAD的解决方法
由于以前做的项目一直用的都是svn,想试一下git尝尝鲜,遇见点问题.记录下来防止以后再出现这种情况,同时希望能帮助到和我一样的初学者. 问题描述: 右键项目-->team-->commi ...
- 取IP的几个方法
ifconfig eth0|grep " inet add"|cut -d":" -f2|cut -d " " -f1 ifconfig e ...