2016-03-21 9 views
0

Wie behalte ich eine Funktion, die mit lokalen Variablen arbeitet, vom Ändern des Wertes eines globalen? Es ist so, als ob ich den Wert per Referenz weitergegeben hätte, ohne es zu wollen.Global verändert sich ständig. Mögliche Weitergabe durch Verweis oder Problem mit dem Umfang? HILFE! Ausführliches Beispiel unter Verbindung

https://github.com/upstageleft/Weird-javascript-problem

Globale Variable ändert sich ständig, wenn Quelldaten (Wert eines Elements aus einer Matrixanordnung in einem Verschluss) auf eine lokale Variable kopiert wird und dann der lokale Variablenwert modifiziert wird.

kann nicht meinen Kopf wickeln um, was los ist, aber Problem macht konsequent in FF, Safari und Chrome.

Link enthält Code und dynamische Anzeige von Variablenwerten mit zu wiederholender Taste. Sollte genug sein, aber Sie können immer Quelle anzeigen, um zu überprüfen.

BEISPIEL DATEN:

In der untenstehenden Liste, das erste Element reflektieren den Wert einer globalen Variable durch einen Wert aus einer Matrixanordnung in einem Verschluß mit Hilfe einer Hilfsfunktion kopiert besiedelt.

Die zweite Liste zeigt, dass der globale Wert geändert wurde, wenn es nicht hätte sein sollen. Der Wert der angegebenen Zelle der Matrix wurde in eine neue Variable kopiert, und diese Variable wurde manipuliert, aber das Ergebnis dieser Manipulation wird irgendwie in die globale Variable und die Matrixvariable zurückkopiert!

  • globVal Anfangswert: 1,1 ← (konstant sein sollte)
  • globvar Anwendungsbereich: [object Window]
  • myObj: {OSRC: "1,1", oX: 2}

Vorher:

  • globVal [0] (global): 1
  • Operation: newVal = Mýval [0] * myObj.oX
  • Mýval [0] (local): 1
  • newVal (local): 2
  • map.see (1,1) (Verschluss): 1,1

After:

  • globVal [0] (global): 2
  • Operation: Mýval [0] = newVal
  • Mýval [0] (lokal): 2
  • newVa l (local): 2
  • map.see (1,1) (Verschluss): 2,1

Hier ist der Code, die Operationen, zusammen mit einer Hilfsfunktion durchführt Werte aus der Matrix zu ziehen, und das Objekt, das den Datenwert enthält, der in den Operationen angewendet werden soll.

Hier sind die Onload-Funktion, die die globale und die Schließung initialisiert, die die Matrix speichert.

CODE BLOCK B 

1 | function init(){ 
2 |  globVal = mxGet('1,1'); // global declared here 
3 |  that = this; 
4 |  doStuff(); 
5 | } 
6 | 
7 | map = (function(){ 
8 |  myHiddenMatrix = [ [ [0,0], [0,1], [0,2] ], 
9 |       [ [1,0], [1,1], [1,2] ], 
10 |      [ [2,0], [2,1], [2,2] ] ]; 
11 |  return { 
12 |   pin: function(x, y, val){ myHiddenMatrix[ x ][ y ] = val; }, 
13 |   see: function(x, y){ return myHiddenMatrix[ x ][ y ]; } 
14 |  } 
15 | })(); 
+0

Sie sollten einen minimalen Fall einbeziehen, der Ihr Problem in der Frage selbst reproduziert. – apsillers

+0

Es scheint, dass Sie Daten ausgelagert haben, die für das Verständnis Ihrer Frage entscheidend sind. Bitte denken Sie daran, alle notwendigen Daten (Code, Konfigurationsdaten, Ausnahme-Name ...) in ** der Frage selbst anzugeben **. Wenn die Verbindung abstirbt oder Ihre Frage ändert, verliert sie die meiste, wenn nicht sogar ihre ganze Bedeutung! –

+0

Danke! Ich habe die Daten eingezogen, aber die Demo-Datei unter [http://upstagelef.net/files/20160321_js_weirdness.html](http://upstagelft.net/files/20160321_js_weirdness.html] zeigt es immer noch am besten. –

Antwort

1

So funktioniert Javascript (und viele moderne Sprachen). Objekte werden (im Wesentlichen) als Referenz übergeben, ob Sie es mögen oder nicht.

Mehr hier: Does Javascript pass by reference?

Wenn Sie Ihre global sind zu setzen, haben Sie es mit der Referenz des Objekts zurück durch mxGet('1,1') in dieser Zeile setzen:

globVal = mxGet('1,1'); 

Wenn Sie möchten, Um stattdessen ein neues Objekt zu sein, müssen Sie globVal tatsächlich auf ein neu erstelltes Objekt wie ein neues Array wie zum Beispiel:

var x = mxGet('1,1'); 
globVal = [ x[0], x[1] ]; 
setzen

Dadurch wird globVal gleich bleiben. Es ist ein subtiler, aber wichtiger Unterschied.

+0

Danke! Ich war dabei, aber es war schwer zu bestätigen, dass dies geschah. –