2011-12-28 157 views
0

可能重複:
Javascript closure inside loops - simple practical example
Javascript: closure of loop?關閉的JavaScript在for循環中

所以我想結果是1,2,3而不是3,3,3 。如何設置上下文/作用域以使作業使用正確範圍的「我」?

function buildJobs(list) { 
    var jobs = []; 
    for (var i = 0; i < list.length; i++) { 
    var item = list[i]; 
    jobs.push(function() {alert(item)}); 
    } 
    return jobs; 
} 

function testJobs() { 
    var jobs = buildJobs([1,2,3]); 
    for (var j = 0; j < jobs.length; j++) { 
    jobs[j](); 
    } 
} 
+0

不是一個確切的重複,但同樣的想法。 – hvgotcodes 2011-12-28 21:13:52

+1

@ hvgotcodes好吧,有超過9000個確切的重複,所以它不是真的很重要,如果那不是:D – Esailija 2011-12-28 21:19:57

+0

精確地說,它的驚人多少次這個問題被問.... – hvgotcodes 2011-12-28 22:39:44

回答

1

裹有另一個函數內部函數會立即執行,並接收i作爲參數:

function buildJobs(list) { 
    var jobs = []; 
    for (var i = 0; i < list.length; i++) { 
    var item = list[i]; 
    (function(i) { 
     jobs.push(function() {alert(list[i])}); 
    })(i); 
    } 
    return jobs; 
} 

現在您要關閉在i是本地包裝功能,這是每次迭代中的一個不同的變量。 (在原始配置每個內部函數閉在相同變量(其值是3通過任何的功能不斷執行的時間)。)

1

當環路生成功能,它們以相同的範圍內的所有共享訪問的變量。在給定的範圍內,只能有一個相同名稱的變量。所以他們都使用循環中的i,並在執行時使用當前值i。而循環運行後,它將永遠是3.

function buildJobs(list) { 
    var jobs = []; 
    for (var i = 0; i < list.length; i++) { 
    (function(i) { 
     var item = list[i]; 
     jobs.push(function() {alert(item)}); 
    })(i); 
    } 
    return jobs; 
} 

所以引入一個新的範圍,捕捉的i當前值只是該次迭代。現在您爲每個生成的函數都有一個新的範圍,每個函數的值都是i

0
function buildJobs(list) { 
    var jobs = []; 

    list.forEach(function(item){ 
     jobs.push(function(){ 
      alert(item); 
     }); 
    }); 

    return jobs; 
} 

forEach