2016-04-22 3 views
0

Ich habe ein Stück Code, den ich versuche, Alarm zu haben 1,2,3. Ich habe Probleme mit Verschlüssen richtig, so dass ich das nicht herausfinden kann.Problem, die Schließungen zu arbeiten

Der ursprüngliche Code:

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

function testList() { 
    var fnlist = buildList([1,2,3]); 
    // using j only to help prevent confusion - could use i 
    for (var j = 0; j < fnlist.length; j++) { 
     fnlist[j](); 
    } 
} 

testList(); 

Ich versuche, so etwas zu buildList() zu tun, um es richtig zu arbeiten:

function buildList(list) { 
    var result = []; 
    for (var i = 0; i < list.length; i++) { 
     var item = 'item' + list[i]; 
     result[i] = function(x) { 
      result.push(function() {alert(item + ' ' + list[x])}); 
     }(i); 
    } 
    return result; 
} 

Ich weiß, ich mache Fehler auf mit der Arbeit Schließungen, ich bin nur nicht sicher, was das Problem ist.

Antwort

0

Ihr zweiter Versuch war näher an der Lösung, aber immer noch nicht funktioniert, weil Ihre inner meisten Funktionsvariablen item von Ihrer Top-Level-Funktion wird die Erfassung: item wird nur immer sich auf die gleiche Instanz, die erstellt wurde, als buildList() Aufruf .

var Der JavaScript-Bereich ist immer an den aktuellen Funktionsaufruf gebunden, nicht an den Codeblock. Daher ist er nicht an die Steuerung von Anweisungen wie for gebunden.

Aus diesem Grund zeigen die Alarme wahrscheinlich den Wert 'item' + (list.length-1) zum Zeitpunkt des Aufrufs buildList().

Da Sie i auf Ihre Schließung sind vorbei, sollten Sie var item innerhalb dieser Funktion deklarieren, zB:

function buildList(list) { 
    var result = []; 
    for (var i = 0; i < list.length; i++) { 
     result[i] = function(x) { 
      // x and item are both local variables of anonymous function declared just above 
      var item = 'item' + list[x]; // or maybe you meant 'item' + x? 
      return function() {alert(item + ' ' + list[x])}; 
     }(i); 
    } 
    return result; 

}

Beachten Sie, dass die Schließung noch einen Verweis auf list erfassen würden, werden die so angezeigt werden Wert, der zum Zeitpunkt des Aufrufs von Funktionen in dem von buildList() zurückgegebenen Array enthalten ist. Auch die lokale Variable item ist komplett optional, Sie könnten alert('item' + x /*or is it list[x]?*/ + ' ' + list[x]) anrufen.

0

Von How do JavaScript closures work?

Beachten Sie, wenn Sie das Beispiel laufen "item2 undefined" wird drei mal alarmiert! Dies liegt daran, dass genau wie in den vorherigen Beispielen nur eine Schließung für die lokalen Variablen für BuildList existiert. Wenn die anonymen Funktionen in der Zeile fnlistj aufgerufen werden; Sie verwenden alle den gleichen Einzelabschluss, und sie verwenden den aktuellen Wert für i und item innerhalb von diesen einen Abschluss (wobei i einen Wert von 3 hat, weil der Loop abgeschlossen hat und Element den Wert 'item2' hat). Beachten Sie, dass wir von 0 indexieren, daher hat item einen Wert von item2. Und das i ++ werde ich auf den Wert erhöhen 3.

Sie benötigen einen Verschluss in jeder Schleife Iteration zu machen, wenn Sie den passenden Wert von i zu speichern sind:

function buildList(list) { 
    var result = [], item, closure; 
    for (var i = 0; i < list.length; i++) { 
    item = 'item' + list[i]; 

    // call this function with the string you wish to store 
    // the inner function will keep a reference to the 'msg' parameter even after the parent function returns 
    closure = (function(msg) { 
     return function() { 
      alert(msg); 
     }; 
     }(item + ' ' + list[i])); 
    result.push(closure); 
    } 
    return result; 
} 

function testList() { 
    var fnlist = buildList([1, 2, 3]); 
    // using j only to help prevent confusion - could use i 
    for (var j = 0; j < fnlist.length; j++) { 
    fnlist[j](); 
    } 
} 

testList(); 

gleiche Frage gestellt here und here. Gleiche Antworten here, here, here, here und wahrscheinlich in einem Dutzend weiterer Orte.

Verwandte Themen