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的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...
随机推荐
- 微调数据库表结构,30 分钟搞定 WordPress 数据库查询缓慢问题
同事的美女图片站,基于 WordPress 搭建的,因为数据越来越多,变得慢,我从 PHP slow log 里面看出是 WordPress 有些查询总是很慢,即使已经安装了页面缓存插件,但是由于页面 ...
- vue源码入口文件分析
开发vue项目有段时间了, 之前用angularjs 后来用 reactjs 但是那时候一直没有时间把自己看源码的思考记录下来,现在我不想再浪费这 来之不易的思考, 我要坚持!! 看源码我个人感觉非常 ...
- Struts的session问题
问题描述: 在一个action中设置session之后,在jsp中得不到session的值或者在另一个action中得不到session的值. 解决方案: 1.不要把session设置成为静态的,同时 ...
- javascript函数创建
函数声明 function add(a,b){ return a+b } 函数表达式 <!--一般函数表达式--> var add = function(){ } <!--立即声明函 ...
- Django_生产环境静态文件配置
需求: 当Django项目运行在线上的时候,需要关闭debug模式,那么Django设置中,静态文件路径配置将会失效,如何解决这个问题? 问题原因: Django默认关闭debug模式,Django错 ...
- 移动端 -webkit-user-select:text; ios10 bug 解决方案
移动端一般body的css.会设置 作用就不解释了: body{ height:100%;min-height:100%; font-family: "微软雅黑",'Helveti ...
- linux 安装icu库
先下载源码包并解压 然后安装 cd /icu/source ./configure --prefix=/usr/local/icu gmake make install
- java 基本数据类型与变量类型
Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. byte,short,char,int,long,float,double Java语言支持的变 ...
- records.config文件参数解释
# Process Records Config File # # <RECORD-TYPE> <NAME> <TYPE> <VALUE (till end ...
- java 如何将 word,excel,ppt如何转pdf--jacob
问题:java 如果将 word,excel,ppt如何转pdf 我个人的观点:windows server下用 jacob; linux server下 用openoffice. PS:1.本文 ...