首页 >社区问答列表 >javascript - js闭包作用域

javascript - js闭包作用域

为什么会输出10 次10 push进去的不应该是 1 - 9吗 这个坑求大神解答

function save_i(){
    var a = [];
    for(var i = 0;i<10;i++){
        a[i] = function(){
            return i;
        }
    }
    return a;   
}

var c = save_i();
for(var i = 0;i<10;i++){
   console.log(c[i]());
    //10次 10
}

  • 黄舟
  • 黄舟    2017-06-28 09:30:398楼

    只需要在for循环执行时,创建一个闭包函数将i值保存起来,既可以依次输出

    function save_i(){
        var a = [];
        for(var i = 0;i<10;i++){
            a[i] = function(i){
                return function() {
                    return i;
                };
            }(i);
        }
        return a;
    }
    
    var c = save_i();
    for(var i = 0;i<10;i++){
       console.log(c[i]());
        //已经变为依次输出
    }

    +0添加回复

  • 回复
  • 阿神
  • 阿神    2017-06-28 09:30:397楼

    在执行点击事件之前,for循环已经执行完,也就是最终获取的是最后 i 的值5。  
    呆神:绑定 和 点击 是两个事件  点击是用户交互的时候发生  绑定在引擎编译代码的时候就发生了~             
    宇神:这样理解吧,你把点击事件当做一个下车事件,而火车从1-4,到4时你才能下车执行事件,此时值为4.

    之前过基础看过的文章
    理解闭包,要求你写过一代码,而且接下来在自己的代码中也能用到,除些之外,就只能死记硬背了。
    老派的国人喜欢让小孩子很小的时候背东西,但是不会和他们讲是什么意思,有时也讲不清,寄希望于在未来的某个时刻自然而然就懂了
    以上
    如果你有一定基础,推荐看我写的日志,再不懂,留言问我
    http://user.qzone.qq.com/2084...

    +0添加回复

  • 回复
  • 女神的闺蜜爱上我
  • 女神的闺蜜爱上我    2017-06-28 09:30:396楼

    function save_i(){
        var a = [];
        for(var i = 0;i<10;i++){
            a[i] = function(i){
                return i;
            };
        }
        return a;   
    }
    
    var c = save_i();
    for(var i = 0;i<10;i++){
       console.log(c[i](i));
    }

    +0添加回复

  • 回复
  • 黄舟
  • 黄舟    2017-06-28 09:30:395楼

     a[i] = function(i){
                return i;
            };

    return的每个i都是引用了外部的同一个i 也就是10

    +0添加回复

  • 回复
  • 黄舟
  • 黄舟    2017-06-28 09:30:394楼

    var fns=[];
    function test(){
        for(var i=0;i<10;i++){
            (function(j){
                fns.push(
                    function(){
                        console.log(j);
                    }
                );
        })(i);    
        
        }
    
    }
    
    test();
    
    for(var k=0;k<fns.length;k++){
        fns[k]();
    }
    

    var变量的作用域是函数作用域,不是块级作用域

    +0添加回复

  • 回复
  • 天蓬老师
  • 天蓬老师    2017-06-28 09:30:393楼

    作用域链在创建的时候就已经生成了, c[i] = function(i){ return i; };运行的时候当前作用域没有i,而上层作用域save_i()的i已经变成10。你认为结果是0~9,是不是你把上层作用域当做全局了

    +0添加回复

  • 回复
  • 黄舟
  • 黄舟    2017-06-28 09:30:392楼

    a[i]赋值的时候是一堆function、也就是并没有执行、也没有拿到i、她的作用域也没取到i

    当你在下面执行的时候、这一堆function都开始找自己作用域能取到的i、也就是循环执行完的10

    +0添加回复

  • 回复
  • 巴扎黑
  • 巴扎黑    2017-06-28 09:30:391楼

    var关键字声明变量作用域为函数作用域, 因此 for 循环中的 i 变量会发生变量提升。 楼主的将for循环中的哪一段改为自执行函数就ok了。eg:
    function save_i(){

    var a = [],
        i = 0;
    for(;i<10;i++){
        a[i] = function(i){
            return i;
        }(i);
    }
    return a;

    }

    +0添加回复

  • 回复