搜尋

首頁  >  問答  >  主體

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
}
扔个三星炸死你扔个三星炸死你2730 天前768

全部回覆(8)我來回復

  • 黄舟

    黄舟2017-06-28 09:30:39

    只需要在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:39

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

    之前過基礎看過的文章
    理解閉包,要求你寫過一程式碼,而且接下來在自己的程式碼中也能用到,除些之外,就只能死記硬背了。
    老派的國人喜歡讓小孩子很小的時候背東西,但是不會和他們講是什麼意思,有時也講不清,寄希望於在未來的某個時刻自然而然就懂了
    以上
    如果你有一定基礎,推薦看我寫的日誌,再不懂,留言問我
    http://user.qzone.qq.com/2084...

    回覆
    0
  • 女神的闺蜜爱上我

    女神的闺蜜爱上我2017-06-28 09:30:39

    雷雷

    回覆
    0
  • 黄舟

    黄舟2017-06-28 09:30:39

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

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

    回覆
    0
  • 黄舟

    黄舟2017-06-28 09:30:39

    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:39

    作用域鏈在創建的時候就已經生成了, c[i] = function(i){ return i; };運行的時候當前作用域沒有i,而上層作用域save_i()的i已經變成10。你認為結果是0~9,是不是你把上層作用域當作全域了

    回覆
    0
  • 黄舟

    黄舟2017-06-28 09:30:39

    a[i]賦值的時候是一堆function、也就是並沒有執行、也沒有拿到i、她的作用域也沒取到i

    當你在下面執行的時候、這一堆function都開始找自己作用域能取到的i、也就是循環執行完的10

    回覆
    0
  • 巴扎黑

    巴扎黑2017-06-28 09:30:39

    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
  • 取消回覆