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 变量问题的更多相关文章

  1. 【Javascript】: for循环中定义的变量在for循环体外也有效

    for循环中定义的变量在for循环体外也有效 <script> (function(){ var a = 111; for(var i=0;i<5;i++){ var carl = ...

  2. bash的循环中无法保存变量

    在bash中,如果循环在一个子shell中运行,那么在循环中对循环外面的变量的更改将在循环退出后不可见.像下面的例子: #!/bin/sh python run.py | while read lin ...

  3. 11 tensorflow在tf.while_loop循环(非一般循环)中使用操纵变量该怎么做

    代码(操纵全局变量) xiaojie=1 i=tf.constant(0,dtype=tf.int32) batch_len=tf.constant(10,dtype=tf.int32) loop_c ...

  4. (python)循环中动态产生变量

    >>> for i in xrange(5): exec 'a'+str(i)+' = '+str(i)+'' >>> a0 0 >>> a1 1 ...

  5. js for 循环中的 变量问题。

    今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...

  6. 关于在for循环中绑定事件打印变量i是最后一次。

    其实函数引用的外部变量都是最后一次的值. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  7. 关于while read line 循环中变量作用域的问题

    前一阵用shell写了一个从数据库中抽取数据生成.xml文件的脚本,要求是每个文件中只生成1000条数据.于是用到了while read line 作为循环. 在制作文件计数器的时候发现了一个问题,在 ...

  8. 【SQL】小心在循环中声明变量——浅析SQL变量作用域

    本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...

  9. 注意for循环中变量的作用域-乾颐堂

    1 2 for e in collections:     pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...

随机推荐

  1. android项目红色感叹号

    Project --> Clean 清理一下,一般要注意的,如果是你的项目文件有错误,特别是xml文件,清理后那个R资源文件会不见的,那就需要你把错误修正后自动生成的.

  2. Java数据持久层框架 MyBatis之API学习二(入门)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  3. python环境搭建--pycharm的安装及使用

    学习网址: --菜鸟教程(2.0和3.0) http://www.runoob.com/python/python-tutorial.html http://www.runoob.com/python ...

  4. IDEA新建Maven项目

    Maven是什么? 当我们在开发一个项目的时候,不可避免地会使用到第三方的类库,而它们又可能依赖着另外的Jar包,又得引入其他Jar包,而且我们很容易就会引漏掉~然后就会报错,有时候报的错会让我们花掉 ...

  5. struts 中自定义action访问方法

    struts中action类继承了ActionSupport  默认实现了execute()方法 struts.xml配置文件中 然后可以配置如下映射: <package name =" ...

  6. 【转】awk用法介绍

    1. 介绍 Awk是由Aho.Weinberger和Kernighan三位科学家开发的,特别擅长文本处理的linux 工具,该工具是 linux 下最常用的工具之一.Awk不是普通的工具,其实,也是一 ...

  7. php之插入排序

    <?phpfunction insertSort($arr) {  //插入排序    $len = count($arr);    for($i=1;$i<$len;$i++){     ...

  8. CentsOS7无网情况下安装mysql5.7

    1.需求就不用讲了,客户现场,政府环境,银行环境,大多是没网的,所以无网安装是很有必要的 mysql下载路径:https://dev.mysql.com/downloads/mysql/ 查看自己Li ...

  9. Java中的null值总结

    自我总结,有什么不对或不到位的地方,请指出,感激不尽! 目的:熟练掌握java中null值出现的情况,避免NullPointerException 代码环境准备:需要引入junit;将代码packag ...

  10. diff和patch命令(1)

    1. diff是对两个集合的差运算,patch是对两个集合的和运算. 2. diff以逐行的方式,比较文本文件的异同处.所是指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子目录 ...