2010-05-13 5 views
6

Erste Frage auf Stackoverflow auf eine Variable verweist :) Hoffe, dass ich werde mich nicht in Verlegenheit bringen ...javascript Umfang Problem, wenn Lambda-Funktion in umschließenden Schleife

ich eine Javascript-Funktion, die eine Liste von Alben lädt und dann erstellt ein Listenelement für jedes Album. Das Listenelement sollte anklickbar sein, also rufe ich jQuery's click() mit einer Funktion auf, die das tut. Ich mache das in einer Schleife. Mein Problem ist, dass alle Elemente dieselbe Klick-Funktion erhalten, obwohl ich versuche, eine neue zu erstellen, die bei jeder Iteration andere Dinge tut. Eine andere Möglichkeit ist, dass die Iterationsvariable irgendwie global ist und die Funktion sich darauf bezieht. Code unten. debug() ist nur eine Verkapselung von Firebugs console.debug(). Hier

function processAlbumList(data, c) { 
for (var album in data) { 
    var newAlbum = $('<li class="albumLoader">' + data[album].title + '</li>').clone(); 
    var clickAlbum = function() { 
    debug("contents: " + album); 
    }; 
    debug("Album: " + album + "/" + data[album].title); 
    $('.albumlist').append(newAlbum); 
    $(newAlbum).click(clickAlbum); 
} 
} 

ist eine Abschrift von dem, was er druckt, wenn die obige Funktion ausgeführt wird, danach sind einige Debug-Linien, die durch mich auf verschiedene Elemente klicken. Es druckt immer "10", was der letzte Wert ist, den die Albumvariable nimmt (es gibt 10 Alben).

Album: 0/Live on radio.electro-music.com 
Album: 1/Doodles 
Album: 2/Misc Stuff 
Album: 3/Drawer Collection 
Album: 4/Misc Electronic Stuff 
Album: 5/Odds & Ends 
Album: 6/Tumbler 
Album: 7/Bakelit 32 
Album: 8/Film 
Album: 9/Bakelit 
Album: 10/Slow Zoom/Atomic Heart 
contents: 10 
contents: 10 
contents: 10 
contents: 10 
contents: 10 

Irgendwelche Ideen? Sie fahren mich die Wand hoch. :)

/Stefan

+2

See: http://stackoverflow.com/questions/1734749/ http://stackoverflow.com/questions/643542/ http://stackoverflow.com/questions/1582634/ http://stackoverflow.com/questions/1331769/ http://stackoverflow.com/questions/1552941/ http://stackoverflow.com/questions/750486/ http://stackoverflow.com/questions/933343/ http://stackoverflow.com/questions/1579978/ http://stackoverflow.com/questions/14139 16/ – CMS

+0

@CMS - Wow, sammelst du nur diese? – harpo

+1

@harpo, ja, ich wurde es leid, die gleiche Frage immer wieder zu beantworten ... :) – CMS

Antwort

8

Sie benötigen einen anderen Rahmen vorstellen, wie so:

var clickAlbum = (function (a) { 
    return function() { 
     debug("contents: " + a) 
    }; 
})(album); 
+0

Wunderbar! Danke vielmals. Ich hatte das Gefühl, dass das eine dieser dummen Neulingssachen war, aber ich wurde wahnsinnig ... –

0

Die album Variable in der inneren Funktion ein Verschluss ist jedoch sein Wert ist nicht gebunden, wenn jeder Funktion wird deklariert. Das bedeutet, dass bei jedem Durchlauf der Schleife die album Schließung auf den Wert geändert wird, den sie in dieser Schleife hat. Es gibt eine detailliertere Erklärung here

Wie Sean (und der Artikel) vorschlagen, können Sie dieses Problem lösen, indem Sie den Gültigkeitsbereich der Variablen ändern.

+0

Yep Seans Vorschlag ließ alles funktionieren. Ich habe tatsächlich versucht, den Bereich zu ändern, indem ich einer lokalen Variablen in der Funktion (und einer Unmenge anderer verrückter Versuche) etwas zugewiesen habe, aber jetzt weiß ich es besser. Danke für den Link - ich werde es überprüfen. –

+0

Gern geschehen. Da die Grundursache ziemlich fortgeschritten ist, könnte es hilfreich für Sie sein, um zu lesen, um ein tieferes Verständnis zu bekommen ... –