Pietro Frizzi: Erstellung dynamischer Variablennamen

Hallo,

lerne gerade die Grundprinzipien von Javascript und habe eine Frage zu dynamischen Variablennamen:

var VariableName = "neuerVariablenName";
this[VariableName] = [1,2,3];
console.log(neuerVariablenName);

// OUTPUT = "[1,2,3]"

Wie lassen sich solche generierten Variablen noch weiter verfeinern?

(var, let, const, global Scope vs. local/function Scope?)

Danke!

  1. @@Pietro Frizzi

    Wie lassen sich solche generierten Variablen noch weiter verfeinern?

    Wie lassen sich solche generischen Fragen noch weiter verfeinern?

    🖖 Stay hard! Stay hungry! Stay alive! Stay home!

    --
    Vielen Eltern dämmert beim Home-Schooling so langsam die Erkenntnis: Lehrer ist wohl doch ein regelrechter Beruf! (@heuteshow)
  2. Hallo Pietro,

    die beste Verfeinerung ist, es zu lassen.

    Der Container für globale Variablen ist das globale Objekt, das bei JavaScript im Browser in der Variablen window zu finden ist.

    Wenn Du - wie empfohlen ist - dein Script im strict-Mode aufrufst und eine Funktion aufrufst, steht in this nichts mehr drin, es hat den Wert undefined.

    D.h. statt this[VariableName] wäre window[VariableName] korrekt.

    ABER: Es ist ganz schlechter Stil, in JavaScript den globalen Namensraum ohne Not zu nutzen. Man modularisiert seinen Code, entweder mit Tools wie ECMAScript-Module oder im Eigenbau durch IIFEs (immediately invoked function expression). Das ist für einen Einsteiger etwas zu hoch, das gebe ich zu, aber Du solltest Dich von Anfang an daran gewöhnen, nicht einfach das globalen Objekt zuzumüllen.

    Ein Eintrag im window-Objekt entspricht einer var-Deklaration auf globaler Ebene. let- und const-Deklarationen werden nicht im window-Objekt eingetragen, sondern im lokalen Scope, deshalb kannst Du über Manipulationen am window-Objekt auch keine let- oder const-Eigenschaften herbeiführen.

    Ich gebe zu, das ist etwas irritierend. Wenn ich keine Funktion schreibe, dann befinde ich mich ja auf globaler Ebene, heißt es. Aber:

    <script>
       var foo=7;
       let bar=42;
       console.log(window['foo']);
       console.log(window['bar']);
    </script>
    

    gibt 7 und undefined aus. "var" ist also globaler als "let". Im Normalfall ist das unerheblich.

    Ein Pattern zum Kapseln deiner Daten, das auf allen Browsern funktioniert, ist die IIFE - sofortausgeführte Funktion. Das sieht so aus:

    <script type="text/javascript">
    (function() {
       "use strict";
    
       // deine Befehle
    })();
    </script>
    

    Dieser Code erzeugt eine namenlose Funktion und führt den Code darin sofort aus. Und zwar im strict mode, d.h. du bekommst sofort eine Fehlermeldung wenn Du eine Variable nicht deklarierst. Programmieren im strict mode ist ebenfalls eine gute Idee - aber möglicherweise funktionieren dann ein paar Tutorials nicht, die für den sloppy-mode gemacht sind.

    Innerhalb dieser Funktion kannst Du Variablen anlegen, weitere Funktionen definieren, und alles tun was Du willst. Der globale Namensraum bleibt unverschmutzt.

    Eine Alternative, die aber im Internet Explorer nicht funktioniert (den noch ein paar Leute verwenden müssen), sind ECMAScript-Module. Die laufen automatisch im strict-Mode und kapseln ebenfalls alles, was darin deklariert wurde, ein.

    <script type="module">
       // Deine Befehle
    </script>
    

    Unterschied zwischen normalen Script-Elementen und module-Elementen ist auch, dass module-Elemente automatisch deferred sind, d.h. das Script wird nicht in dem Moment ausgeführt wo der Browser es antrifft, sondern erst dann, wenn das Dokument vollständig geladen ist. Um diesen Moment abzuwarten, muss man ohne Module einen sogenannten ready-Handler programmieren, bei Modulen gibt's das geschenkt.

    Beide Modularisierungstechniken haben gemein, dass Du daran gehindert wirst, die veraltete Ereignis-Registrierung mit onxxxx Attributen zu benutzen. Wenn Du beispielsweise auf ein click Event eines Buttons reagieren willst, hat man früher <button onclick="buttongeklickt()"> geschrieben. Wenn dein Code in einem Modul steht, dann geht das nicht. Aber man soll sowas ohnehin nicht mehr tun, sondern addEventListener verwenden.

    <button type="button" id="okButton">OK</button>
    
    <!-- Mit IIFE -->
    <script type="text/javascript">
    (function() {
       "use strict";
    
       let okButton = document.getElementById('okButton');
       okButton.addEventListener('click', HandleOkButtonClickEvent);
    
       function HandleOkButtonClickEvent(e) {
          // auf ok reagieren
       }
    })();
    </script>
    
    <!-- Als Modul -->
    <script type="module">
       let okButton = document.getElementById('okButton');
       okButton.addEventListener('click', HandleOkButtonClickEvent);
    
       function HandleOkButtonClickEvent(e) {
          // auf ok reagieren
       }
    </script>
    

    Auf diese Weise klappt das, und dein HTML bleibt von JavaScript-Schnipseln frei. So baut man das heute.

    Rolf

    --
    sumpsi - posui - obstruxi