2016-09-20 10 views
1

Dies beinhaltet einige Angular, aber ich denke, es ist vor allem eine reine JavaScript-Bereich Frage. Ich habe eine Direktive, die ein paar Mal auf meiner Seite mit einem ng-repeat aufgerufen wird. Wenn es zuerst aufgerufen wird, habe ich die variable current_index gleich der Indexnummer der Markierung auf der Seite Einheit wie folgt:Warum wird diese primitive Variable durch Verweis statt durch Wert an eine Funktion übergeben?

var current_index = scope.$eval(attrs.index); 

ich es dann an eine Funktion, die auf eine halbe Sekunde Verzögerung ist.

g.append("g") 
    .transition() 
    .duration(500) //Half second delay 
    .on("start", function(){ 
     tick(current_index); //Passing the current_index variable 
    }); 

jedoch durch die Zeit, diese Funktion für jede Instanz des Tags genannt wird, ist current_index auf die Nummer des letzten Index immer gleich, die aufgerufen wurde (Beispiel: Wenn ich 3-Tags meine Richtlinie entspricht, und Druck console.log(current_index); in meiner Funktion, die auf einer Verzögerung ist, wird es 2 3 mal drucken, anstatt 0, 1, 2.

function tick(index){ 
     console.log(index); 
    } 
// Prints 2, 2, 2 

Allerdings, wenn ich eine neue Variable einführen, a, und setzt es gleich current_index, und übergibt, In die Funktion funktioniert es wie erwartet.

var current_index = scope.$eval(attrs.index); 
var a = current_index 

g.append("g") 
.transition() 
.duration(500) //Half second delay 
.on("start", function(){ 
    tick(a); //Passing the a variable 
}); 


function tick(index){ 
     console.log(index); 
    } 
// Prints 0, 1, 2 

Es scheint, dass current_index als Objekt übergeben wird, und a als primitives übergeben wird, aber beide number zurück, wenn ich die typeof Funktion tun. Was ist denn hier los?

+1

Es ist in allen Fällen, die Sie zeigen, nach Wert übergeben, aber Sie erhalten das falsche Verhalten wegen des Umfangs. In der Version mit der 'a' -Variable deklarieren Sie wirklich die 'a'-Variable wie in der Zeile nach und im selben Bereich wie die' current_index'-Deklaration? (Siehe auch [diese Frage] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example).) – nnnnnn

+0

thats ist Problem. Sie müssen es in Schließung wickeln – YOU

+0

Ich konnte die Antwort in der verknüpften Frage folgen, aber ich verstehe immer noch nicht, warum die Einführung einer neuen Variablen, nur eine Zeile darunter, wäre anders. Ich würde denken, sie würden den gleichen Umfang haben und die neue Variable wäre auch falsch – apdm

Antwort

1

Dies kann verwirrend sein. Aber denken Sie daran, dass Sie current_index hier nicht übergeben, sondern eine Funktion definieren, die eine Schließung hat und über diese Schließung auf die Variable current_index im übergeordneten Bereich zugreifen kann.

.on("start", function(){ 
    tick(current_index); // you have access to this because of the closure 
}); 

Also, wenn Sie den Wert CURRENT_INDEX zu ändern, was auch immer CURRENT_INDEX ist, wenn die anonyme Funktion, die Sie dort erstellt ausführt, das ist, was übergeben wird, um tick().

Dies ist einer der Gründe, warum das Erstellen von Funktionen innerhalb von for-Schleifen gefährlich ist. Sie müssen entweder eine sofort aufgerufene Funktion verwenden, die den aktuellen Index als Argument akzeptiert, und die Funktion, die Sie ausführen möchten, zurückgeben. Oder Sie können die übergebene Funktion binden:

Verwandte Themen