• 深入浅出:了解for循环中保留i值得方法


    一、保留i值 

    通常情况下,因为一些效果我们需要获取到for循环中的i的值,但是往往拿到的都是最后一个i的值。下面介绍几种方法可以获取到i的值

    1.自定义属性:

    arr[i].index = i;
    以一个事件为例
    例如:

    for(var i =0;i<arr.length;i++){
    arr[i].index = i;
    arr[i].onclick = funtion(){
    var index = this.index;
    console.log(index)  //  ===>1,2,3,4
    }

    }

    2 自执行函数:
    for(var i=0;i<5;i++){
    (function(n){

    setTimeout(function(){ 

    console.log(n); 

    },1000)

    })(i)}

    ==>0,1,2,3,4

    3 闭包:
    var list =document.querySelectorAll("ul>li");
    for(var i=0;i<list.length;i++){
    list[i].onclick=function(i){
    return function(){
        console.log(i)
        }
        }(i);
    }
    4 使用ES6语法中的let代替var关键字:
    var list =document.querySelectorAll("ul>li");
    for(let i = 0 ; i < list.length ; i++) {
        list[i].onclick=function(){
        console.log(i)
        }
    }

    ==>0,1,2,3 

    推荐链接:
    https://www.cnblogs.com/shipskunkun/p/5695784.html

    二、延时器保留i值的方法

     1.  先看一个经典的for循环嵌套延时器的案例

    for (vari = 0; i < lg; i++) {// lg = 6

    setTimeout(function () {
    console.log(i); //此时输出为 6 个 6
    }, 1000)
    }
    我们想要的结果是在for循环中一次打印出 i 的 值。即0,1,2,3,4,5;但是输出6个相同的个数字是什么原因呢?

    这主传进去要是因为setTimeout的执行时异步执行的,而for循环的执行却非常的快,所以,在1s后执行定时器函数时, i  已经 循环到了最大值6,其他的i值已经被销毁,此时再执行定时器,则是把 i=6传进去了,所以造成了这样的结果。 

    第一种方法:将延时器中的函数用一个自执行函数包起来,把每个循环中的 i 在被回收之前直接传入到自执行函数中,这样就可以避免被回收:如下: 

    for (var i = 0; i < lg; i++) {//lg = 6
    setTimeout((function (a) {
    console.log(a);//操纵变量a,和i无关 此时输出为0,1,2,3,4,5
    })(i), 1000);//将 i 作为变量传入
    }
    但是这样写会出现一个问题,函数直接打印了,并没有一秒的延迟,原因是将自执行函数放在定时器中,会直接执行,并不是1秒后再执行,所以在这种方法上做了一些改进,即第二种方法:
    第二种方法:将延时器整个的包裹在一个子执行函数中,这样就相当于同时定义了6个延时1s的延时器:
    for (var i = 0; i < lg; i++) {//lg = 6
    (function (a) {//自执行函数,获取i
    setTimeout(function () {
    console.log(a);//操纵变量a,和i无关 此时输出为 0,1,2,3,4,5 且在1s延迟后输出
    }, 1000)
    })(i)
    }

     
    第三种方法:因为ES6的let会在局部作用域内保留i值


    for (let i = 0; i < 5; i++) {
    setTimeout(function () {
    console.log(new Date, i);
    }, 1000);
    }

    这样就完美的解决问题了;如果你想要每隔一秒输出一个值,而不是同时输出,则可以将参数传进时间中: 

    for (var i = 0; i < lg; i++) {//lg = 6
    (function (a) {//自执行函数,获取i
    setTimeout(function () {
    console.log(a);//操纵变量a,和i无关 此时输出为 0,1,2,3,4,5 且在1s延迟后输出
    }, a * 1000)//将 i 的值传进来 ,这样就可以每个一秒输出一个值
    })(i)
    }

    setInterval定时器和setTimeout 不同,因为是执行次数的原因,不能将 i  的值传进时间中,会造成多次重复; 


  • 相关阅读:
    hibernate课程 初探单表映射2-7 hbm配置文件常用设置
    SQL partition (小组排序)
    修改input的text 通过jquery的html获取值 未变化
    ASP.NET MVC5使用Area区域
    MVC 缓存
    C# 后台访问webapi
    分布式系统
    滴滴出行技术总监:关于技术选型的那些事儿
    Json Self referencing loop detected
    VMWare 安装 Eclipse
  • 原文地址:https://www.cnblogs.com/yunshangwuyou/p/9309483.html
Copyright © 2020-2023  润新知