Linuchs: Gültigkeit JS-Variable global?

Moin,

ich habe fast zwei Stunden nach einem Fehler gesucht, weil die Variable einer .js Datei in einer anderen .js Datei nicht erkannt wird.

<script src="css/standard.js"></script><script src="css/reportIframeHeight.js"></script>

standard.js:

var requestObj;
function makeRequestObject( requestName ) {
  …
  requestObj = new XMLHttpRequest();
}

reportIframeHeight.js:

function reportIframeHeight( HOST, gif_name ) {
  // requestObj erzeugen, falls noch nicht vorhanden
  if ( typeof requestObj != "object" ) {
    makeRequestObject( "reportIframeHeight.js" ); // standard.js erzeugt var requestObj;
  }
  // überprüfen, ob requestObj erzeugt wurde
  if ( typeof requestObj != "object" ) {
    alert("css/reportIframeHeight.js: XMLHTTP-Instanz var requestObj wurde nicht erzeugt");
  }
}

Obwohl (mit alert ausgegeben) requestObj in Datei A erzeugt wurde, ist es in Datei B nicht bekannt. Warum?

Ich habe den Fehler umgangen, mit return requestObj; und var requestObj = makeRequestObject(), aber warum kann ich die "globale" Variable nicht ansprechen?

Linuchs

  1. Tach!

    Ich habe den Fehler umgangen, mit return requestObj; und var requestObj = makeRequestObject(), aber warum kann ich die "globale" Variable nicht ansprechen?

    Das ist auch die bessere Variante, dass man die Dinge durchreicht, als dass irgendwer etwas irgendwo in der Botanik ablegt und andere zu diesem Irgendwo hingehen und sich das holen. Beim Durchreichen sieht man den Fluss deutlich besser, als es bei nebenbei passierenden Dingen der Fall ist.

    dedlfix.

    1. ... als dass irgendwer etwas irgendwo in der Botanik ablegt und andere zu diesem Irgendwo hingehen und sich das holen.

      Um im Bild zu bleiben: Warum ist das "etwas" verschwunden, wenn man es holen möchte?

      Linuchs

      1. Tach!

        ... als dass irgendwer etwas irgendwo in der Botanik ablegt und andere zu diesem Irgendwo hingehen und sich das holen.

        Um im Bild zu bleiben: Warum ist das "etwas" verschwunden, wenn man es holen möchte?

        Weiß ich nicht. Das ist eine Frage, die man mit Debugging untersuchen müsste. Dateien bilden jedenfalls keinen eigenen Scope.

        Setze Breakpoints auf alle schreibenden Vorgänge und die Stelle, an der es gelesen werden soll. Prüfe die Reihenfolge, mit der diese angesprungen werden.

        dedlfix.

  2. Aloha ;)

    aber warum kann ich die "globale" Variable nicht ansprechen?

    Aus dem was uns hier an Informationen vorliegt geht das noch nicht hervor. (Will sagen: Ich sehe keinen offensichtlichen Fehler.) Im Zweifelsfall handelt es sich um eine race condition oder um ein ungewolltest / unbewusstes Überschreiben an anderer Stelle.

    Es gilt aber ohnehin das, was dedlfix sagte, es ist also eher müßig, da noch nach dem Fehler zu suchen. Besser umschreiben und nicht auf den globalen Kontext setzen.

    Grüße,

    RIDER

    --
    Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
    # Twitter # Steam # YouTube # Self-Wiki # Selfcode: sh:) fo:) ch:| rl:) br:^ n4:? ie:% mo:| va:) js:) de:> zu:} fl:( ss:) ls:[
    1. Unter der Annahme, dass der Code so aussieht wie gezeigt - sprich: makeRequestObject endet mit der Zuweisung an requestObj und die 6 Zeilen von reportIframeHeight stehen genau so hintereinander - kann es weder eine Race Condition noch ein Überschreiben sein. makeRequestObject wird synchron als Helper aufgerufen und das Ergebnis sofort verwendet; da JavaScript singlethreaded[1] ist, sollte das passen.

      Ich sehe drei Fehlermöglichkeiten:

      • Irgendwo in makeRequestObject steht ein unschuldiges var requestObj herum
      • Irgendwo in reportIframeHeight steht ein unschuldiges var requestObj herum (gerne auch weiter unten, das schleicht sich dann heimlich zum Start der Funktion)
      • makeRequestObject und das davor stehende var requestObj befinden sich entgegen Deiner Überzeugung nicht im globalen Scope.

      Das Requestobjekt zurückzugeben statt es in die globale Flora zu pflanzen ist aber auf jeden Fall der bessere Weg. Ich weiß nicht, ob man einen XMLHttpRequest wiederverwenden kann oder sollte. Vermutlich nicht. Insofern macht es wenig Sinn, das Objekt global auf Halde zu haben und das Singleton-Pattern zu realisieren, nach dem es hier aussieht. Ablauf sollte sein: Request erzeugen, abfeuern, Eventhandler drankleben, vergessen. Der Rest geschieht im Eventhandler.

      Rolf


      1. Ja ich weiß, es gibt Web Worker, aber die haben einen eigenen globalen Scope ↩︎