SELFHTML wird 30 Jahre alt! → Veranstaltungs-Ankündigung.
Benutzer:Rolf b/JavaScript Variable
Eine Variable lässt sich am besten mit einem Behälter, der genau einen Wert aufnehmen kann, vergleichen. Der Behälter ist ein von JavaScript verwalteter Speicherplatz mit einem (unveränderlichen) Namen. In einem solchen Speicherplatz kann man beliebige Werte ablegen und später wieder verwenden. Man kann einen vorhandenen Wert auch beliebig oft durch andere Werte ersetzen. Die Möglichkeit, Werte zu errechnen, in Variablen zu speichern und weiterzugeben, gibt Programmen ihre Flexibilität.
In JavaScript gibt es drei verschiedene Möglichkeiten Variablen zu deklarieren:
- let: deklariert eine lokale Variable im Block Scope
- const: Symbolische Konstante; deklariert eine unveränderliche Variable
- var: der Vater der Variablen;
deklariert eine Variable unabhängig von ihrem Scope (Gültigkeitsbereich).
ToDo (weitere ToDos)
Dieser Artikel ist eine Textübernahme von Benutzer:Rolf_b/JavaScript_Variable.
Ich habe ihn soweit umgestellt, dass erst einmal das beschrieben wird, was allen 3 Schlüsselwörtern gleich ist:
- Deklaration
- Zuweisung und Initialisierung
- Datentypen und die implizierte Umwandlung.
(Hier muss geschaut werden, was bereits bei JavaScript/Datentyp erklärt wurde, bzw. werden wird (Ist ja auch noch Baustelle!))
Erst in Kap. 3 werden die Schlüsselwörter let, const und var näher erklärt.
In Kap 4. Kommt der scope - Hier ist die Frage, inwieweit man den schon bei var erklären soll.
Ich hätte am Liebsten, dass man in jedem Kapitel den strict mode einführt und sich dann nicht um Altlasten kümmert. Die müssen einmal irgendwo erklärt werden! Aber wo??? → HIER
Dazu gibt es noch JavaScript/Scope - wo hört dieses Kapitel auf und fängt der nachste Artikel an???
--Matthias Scharwies (Diskussion) 09:19, 19. Jan. 2025 (CET)
Inhaltsverzeichnis
Deklaration
Um eine Variable zu erzeugen, muss sie für JavaScript bekannt gemacht („deklariert“) werden. Diese Deklaration verfolgt mehrere Zwecke.
- es soll helfen, Programmfehler durch einen Vertipper in Variablennamen zu vermeiden
- der Ort der Deklaration legt fest, welche Programmteile auf die Variable zugreifen können und wie lange die Variable existiert
- die verwendete Deklarationsanweisung legt weitere Regeln für den Zugriff fest
let länge,
breite,
fläche;
Im Beispiel werden mit dem Schlüsselwort let drei Variablen deklariert. Damit stehen sie innerhalb des Anweisungsblocks, in dem sie notiert worden sind, zur Verfügung.
Da ein Behälter immer irgendetwas enthalten muss, und sei es auch nur Luft, sieht JavaScript für Variablen, die man deklariert hat, in denen aber noch nichts gespeichert wurde, den speziellen Wert undefined vor.
Zuweisung und Initialisierung
Um sinnvoll mit Variablen arbeiten zu können, muss man Werte in ihnen speichern.
Diese Werte werden mit dem Zuweisungsoperator =
der Variable zugewiesen. Weil es häufig vorkommt, dass man einer deklarierten Variablen gleich einen Wert geben möchte, lassen sich Deklaration und Zuweisung auch kombinieren, man spricht dann von Initialisierung.
// Deklaration und Zuweisung getrennt
let breite;
breite = 210;
// Deklaration und Zuweisung zur Initialisierung zusammengefasst
let breite = 210;
// Initialisierung ist auch möglich, wenn mehrere Variablen auf einmal deklariert werden
let breite = 210,
länge = 297;
In den oberen Beispielen wird den Variablen breite
und länge
jeweils ein Literal zugewiesen. Literale sind feste Werte, die direkt im Code angegeben werden.
Arbeiten mit Variablen
Der große Vorteil einer Variable ist, dass man ihr etwas zuweisen und damit arbeiten kann. Anstatt also feste Werte im Programm zu verwenden, bezieht man sich auf den Wert, der in einer Variable gespeichert wurde. Hierdurch werden Programme erst flexibel und Funktionen können verallgemeinert werden.
So kann man unsere beiden Variablen nun zur Flächenberechnung weiterverwenden:
const fläche = länge * breite;
Die Variable fläche
wird kein Literal, sondern ein Ausdruck zugewiesen. In einem solchen Ausdruck kann man beliebig Literale und andere Variablen verwenden.
Sie wird mit dem Schlüsselwort const deklariert, da sich der Wert - nämlich die Multiplikation von länge
und breite
nicht ändert. Eine erneute Zuweisung würde zu einem Fehler führen.
// Fix und nicht flexibel
let berechneDiagonale = Math.sqrt(210 * 210 + 297 * 297);
// Flexibel durch Verwendung von Variablen
const berechneDiagonale = Math.round(Math.sqrt(breite * breite + höhe * höhe));
// weg????
function berechneDiagonale(breite, höhe)
{
return Math.round(Math.sqrt(breite * breite + höhe * höhe));
}
let diagonaleVonA4 = berechneDiagonaleVonA4Seite(); // starr
let diagonaleVonA5 = berechneDiagonale(210, 148); // flexibel und wiederverwendbar
let diagonaleVonA3 = berechneDiagonale(420, 297); // flexibel und wiederverwendbar
Die Initialisierung mit einem Ausdruck ist natürlich auch für let
und var
verwendbar.
Ein weiterer Vorteil und Nachteil zugleich ist, dass es einer Variable erstmal egal ist, was sie für einen Wert beinhaltet. Dies kann eine Zahl, eine Zeichenkette, ein Array, eine Funktion oder sonstiges Objekt sein. Wenn man hingegen einen bestimmten Typ erwartet, der verarbeitet werden soll, dann muss man unter Umständen zuerst prüfen, ob das Objekt in der Variable kompatibel ist oder konvertiert werden kann.
JavaScript führt eine implizite Typkonvertierung durch, wenn man selber nicht darauf achtet. Kann der Typ für eine bestimmte Operation nicht konvertiert werden, dann wird eine Ausnahme ausgelöst oder es wird ein Standardwert zurückgegeben. Es werden aber auch Funktionen bereitgestellt, um eine explizite Typkonvertierung durchzuführen. Diese geben mehr Kontrolle, wie man auf eine unzureichende Konvertierung reagieren möchte.
Loose Typing - Dynamische Typisierung
JavaScript ist eine Sprache mit loser Typisierung, d. h. Variablen sind nicht an einen bestimmten Datentyp gebunden. Stattdessen können sie Werte eines beliebigen Typs enthalten, und der Typ kann sich dynamisch ändern.
let length = 12; // Number
length = 12 + 'cm'; // length wird ein String: '12cm'
let message = '42';
message = message * 2; // message wird eine Zahl: 84
- Die Variable
length
beginnt als Zahl (12), ändert sich aber in einen String ('12cm'
), wenn sie mit'cm'
konkateniert (verkettet) wird. - Die Variable
message
beginnt als Zeichenkette ('42'
), ändert sich aber aufgrund der impliziten Typenzwangsverknüpfung während der Multiplikation in eine Zahl (84
).
Die lose Typisierung von JavaScript bietet zwar Flexibilität, kann aber auch zu Fehlern führen, wenn sie nicht sorgfältig gehandhabt wird. Hier sind einige Best Practices:
- Verwende
const
oderlet
mit Bedacht - Vermeide es, Variablen Werte unterschiedlichen Typs zuzuweisen, es sei denn, es ist absolut notwendig.
Verwende stattdessen neue Variablen, um Klarheit zu schaffen:
const length = 12; // Number
const lengthWithUnit = length + 'cm'; // String
Anstatt sich auf implizite Typenzwänge zu verlassen, solltest du Typen explizit konvertieren, um deinen Code vorhersehbar zu machen:
let input = '42';
let numberInput = Number(input); // Convert string to number
console.log(numberInput * 2); // 84
Mithilfe der Number()-Funktion wird der String in eine Zahl umgewandelt.
Validiere deine Variablen Stelle vor der Durchführung von Operationen sicher, dass die Variablen dem erwarteten Typ entsprechen:
let value = "42";
if (typeof value === 'number') {
console.log(value * 2);
} else {
console.log("Value is not a number");
}
Mithilfe des typeof-Operators wird überprüft ob es sich bei value
auch wirklich um eine Zahl handelt.
Ungültigkeit der Vermischung von Typen in Ausdrücken
Vermeide Operationen, an denen unterschiedliche Typen beteiligt sind (z. B. das Addieren von Zahlen und Zeichenketten), da dies zu unerwarteten Ergebnissen führen kann:
console.log(12 + "3"); // "123" (string concatenation)
console.log(12 - "3"); // 9 (string is coerced into a number)
Wenn du diese Empfehlungen beachtest, kannst du die Vorteile der losen Typisierung von JavaScript nutzen, ohne Fehler oder Verwirrung in deinen Code zu bringen.
Hauptartikel: Datentypen in JavaScript
Schlüsselwörter
Variablen in JavaScript können mit drei Schlüsselwörtern deklariert werden. Im Folgenden sollen die Unterschiede erläutert werden.
let
Eine Anweisung mit dem Schlüsselwort let deklariert eine oder mehrere Variablen innerhalb des Anweisungsblocks, in dem sie notiert wird. Steht die let-Anweisung außerhalb jeglicher Anweisungsblocks, ist die Variable nach Ausführung der let-Anweisung überall sichtbar und kann überall verwendet werden.[1][2][3]
let number = 42;
console.log(number); // 42
let local;
console.log(local); // undefined
local = 'value';
console.log(local); // value
Eine unter Verwendung von let deklarierte Variable kann, aber muss nicht bei ihrer Deklaration initialisiert werden. Wird ihr bei der Deklaration nicht explizit ein Wert zugewiesen, dann wird sie stattdessen automatisch mit dem primitiven Wert undefined
initialisiert.
console.log(alter); // Abbruch!
let alter;
let
deklarierte Variable ist erst bekannt, wenn die let-Anweisung ausgeführt wurde. Eine vorzeitige Verwendung führt zum Script-Abbruch.
Sichtbarkeit
Variablen, die unter Verwendung des Schlüsselwortes let deklariert werden, besitzen Block Scope, das heißt, sie sind nur innerhalb des jeweiligen Blocks sichtbar, in dem sie deklariert wurden. Von außerhalb des Blocks können sie hingegen nicht referenziert werden.
let local = 32;
{
let local = 64;
console.log(local); // 64
}
console.log(local); // 32
In dem Beispiel oben wird zunächst im globalen Gültigkeitsbereich eine Variable mit dem Bezeichner local
deklariert und mit einem Wert initialisiert. Dabei wird der Bezeichner der Variable an die lexikalische Umgebung des globalen Ausführungskontexts gebunden. Sobald der Programmfluss die öffnende geschweifte Klammer erreicht, die den Beginn eines Anweisungsblocks markiert, wird für diesen Block eine eigene lexikalische Umgebung erzeugt und die innerhalb des Blocks deklarierte Variable mit demselben Bezeichner daran gebunden. Folglich wird die Referenz, die an die Methode log
innerhalb des Blocks übergeben wird, zu dem Wert der innerhalb des Blocks deklarierten Variable aufgelöst. Nachdem der Programmfluss den Scope des Blocks wieder verlassen hat, ist die zuvor durch die Variable in dem Block verschattete Variable des globalen Scopes wieder sichtbar, sodass bei dem zweiten Aufruf der Methode log
entsprechend ihr Wert ausgegeben wird.
for (let index = 2; index <= 5; index ++) {
let number = Math.pow(index, 3);
console.log(number); // 8, 27, 64, 125
}
console.log(index); // Reference Error
Darüber hinaus sind Variablen die mittels let in einem Schleifenkopf deklariert werden auch nur innerhalb der Schleife sichtbar, außerhalb jedoch nicht. Das heißt, bezogen auf das Beispiel oben, kann die Zählvariable index
nur im Kopf der Schleife und in deren Anweisungsblock referenziert werden, während der Versuch der Referenzierung nach verlassen der Schleife einen Fehler produziert. Die Variable number
hingegen ist in ihrer Sichtbarkeit auf den Anweisungsblock beschränkt, der bei jedem Schleifendurchlauf neu initialisiert wird.
function test ( ) {
// temporal dead zone
console.log(typeof number); // Reference Error
// declaration
let number = 128;
}
test( );
Schließlich ist in diesem Zusammenhang zu beachten, dass zwar die Bindung von Variablenbezeichner und lexikalischer Umgebung beim Eintritt in den jeweiligen Gültigkeitsbereich erfolgt, aber die Variable vor ihrer Deklaration im Code nicht mit einem Standardwert initialisiert wird. Das heißt, anders als bei Variablen die mittels var deklariert werden, können mit let deklarierte Variablen, ebenso wie Konstanten, nicht vor ihrer eigentlichen Deklaration referenziert werden. Dies erzeugt immer einen Fehler, selbst dann, wenn wie in dem Beispiel oben der Operator typeof verwendet wird, da es sich hierbei nicht um eine unauflösbare Referenz, sondern lediglich um eine noch nicht initialisierte Variable handelt. Die Zeit vom Eintritt in den Gültigkeitsbereich bis zur Deklaration der Variable wird auch Temporal Dead Zone genannt.
Redeklaration
Wird innerhalb desselben Gültigkeitsbereichs mehr als einmal eine Variable mit dem Schlüsselwort let und mit demselben Bezeichner deklariert, dann wird dadurch ein Typfehler erzeugt und das Programm kann nicht ausgeführt werden. Hier verhält es sich also anders als bei Variablen die mit var deklariert werden, denn bei diesen Variablen wird ohne Fehler und ohne Warnung nur eine Variable an die lexikalische Umgebung gebunden, welcher dann gegebenenfalls durch die Redeklaration ein neuer Wert zugewiesen wird.
// Type Error before execution
let clone = 'Dolly';
let clone = 'Jango Fett';
Dabei spielt es im Übrigen aus Sicht einer mit let deklarierten Variable keine Rolle, ob eine gleichnamige Variable ebenfalls mittels let deklariert wurde oder ob es sich dabei um eine mit var deklarierte Variable handelt. Ebenso wird ein Fehler erzeugt, wenn im Scope der Variable eine Funktion mit demselben Bezeichner deklariert wurde oder wenn in einer Funktion ein formaler Parameter mit demselben Namen notiert wurde.
Allerdings ist zu beachten, dass wenn eine Variable über ihre Lebenszeit hinweg immer den gleichen Wert behält, es besser ist, mittels const eine Konstante zu deklarieren, da dies dem Code etwas mehr Transparenz verleiht und es darüber hinaus Optimierungen des Programms bei dessen Interpretation ermöglicht.
const
Mit dem Schlüsselwort const wird eine unveränderbare (immutable) symbolische Konstante deklariert. Dabei wird analog zur Initialisierung einer Variable ein Bezeichner an einen Wert gebunden, mit dem Unterschied, dass bei einer Konstante diese Bindung später nicht mehr verändert werden kann.[4]
Eine Konstante kann grundsätzlich überall da deklariert werden, wo auch eine Variable deklariert werden darf. Im Gegensatz zu einer Variable muss eine Konstante jedoch bei ihrer Deklaration mit einem Wert initialisiert werden, da sonst ein Syntaxfehler geworfen wird, der die Ausführung des Programms abbricht.
const archimedes = 3.142;
const euler = 2.718,
pythagoras = 1.414;
const avogadro = 6.02214E-23, theodorus; // Syntax Error
Man kann Konstanten einzeln deklarieren, oder durch Komma getrennt auch mehrere auf einmal. Für verbesserte Lesbarkeit kannst du eine Auflistung auch auf mehrere Zeilen verteilen.
Anders als z. B. bei PHP werden Konstanten in JavaScript nicht in Großbuchstaben geschrieben.[5]
Ebenso wie bei Variablen darf der zugewiesene Wert von jedem beliebigen Datentyp sein, das heißt, es können nicht nur primitive Werte hinterlegt werden, sondern auch Objekte und damit auch Arrays und Funktionen. Genauso gut kann der Inhalt einer anderen Variablen oder Konstanten oder der Wert eines Ausdrucks zugewiesen werden
const addiere = function(x, y) { return x + y; };
const object = {
wert: 42,
name: 'ultimate answer'
};
const number = object.wert;
const question = number == 42 ? "life, universe and everything" : "what's up?";
Wird eine Konstante mit einem Objekt initialisiert, dann ist nur dieser Verweis auf das Objekt vor Veränderung geschützt. Das Objekt selbst (oder das Array oder die Funktion) hingegen nicht! Wird also wie in dem folgenden Beispiel eine Konstante mit einem Objektliteral oder einem Array initialisiert, dann können diese Objekte weiterhin manipuliert werden. Der Versuch, die Konstante mit einem anderen Wert zu ersetzen, führt hingegen zu einem TypeError.
const object = {
wert: 42,
name: 'ultimate answer'
};
object.wert = 47; // Eigenschaft ändern: funktioniert
object.shipNumber = '1701'; // Eigenschaft hinzufügen: funktioniert
delete object.wert; // Eigenschaft entfernen: funktioniert
const array = [ ];
array.push(Infinity); // Array-Element hinzufügen: funktioniert
array = [ 3, 2, 1]; // Verweis auf das Array überschreiben: TypeError
In einer Konstantendeklaration ist auch Destrukturierung von Arrays oder Objekten möglich. Falls die Destrukturierung dabei auf fehlende Arrayeinträge oder Objekteigenschaften stößt, wird die Konstante mit undefined
initialisiert.
const greek = ['ἄλφα', 'Ωμέγα']
const [alpha, gamma, omega] = greek;
console.log(alpha, gamma, omega);
// Ausgabe: ἄλφα Ωμέγα undefined
const ship = {
ident: 'NCC-1701',
name: 'USS Enterprise',
captain: 'Robert April'
}
const {ident, name, captain, doctor} = ship;
console.log(`Die ${name} unter dem Kommando von ${captain} ist registriert als ${ident}.`);
console.log(`Schiffsarzt ist ${doctor}`);
// Ausgabe:
// Die USS Enterprise unter dem Kommando von Robert April ist registriert als NCC-1701.
// Schiffsarzt ist undefined
Sichtbarkeit
Ebenso wie Variablen die unter Verwendung des Schlüsselwortes let deklariert werden ist der Gültigkeitsbereich (Scope) von Konstanten auf den Block beschränkt, in dem die Deklaration notiert wurde. Wird eine Konstante also wie in dem folgenden Beispiel innerhalb des Anweisungsblocks einer bedingten Anweisung notiert, dann kann sie von außerhalb dieses Blocks nicht referenziert werden.
if (true) {
const proton = 'baryon';
}
console.info(proton); // Reference Error
Erreicht der Programmfluss einen Anweisungsblock, dann wird für diesen Block eine lexikalische Umgebung (Lexical Environment) erzeugt, die über eine Referenz auf die äußere Umgebung sowie über ein Verzeichnis der innerhalb des Blocks deklarierten Variablen und Konstanten verfügt (Environment Record). Wird in dem Block eine Konstante deklariert, dann wird deren Bezeichner dem Verzeichnis hinzugefügt, das heißt, er wird an die lexikalische Umgebung des Blocks gebunden.
function constant ( ) {
// temporal dead zone
console.info(typeof planck); // Reference Error
// declaration
const planck = 'quantum of action';
};
constant( );
Aber anders als bei Variablen die mittels var deklariert werden und ebenso wie bei Deklarationen mittels let, kann eine Konstante grundsätzlich nicht vor ihrer Deklaration referenziert werden. Dies erzeugt immer einen Fehler. Selbst dann, wenn wie in dem Beispiel der Operator typeof verwendet wird. Der Grund dafür ist, dass die Konstante zwar beim Eintritt in den jeweiligen Gültigkeitsbereich an dessen lexikalische Umgebung gebunden wird, dabei jedoch keine Initialisierung mit einem Wert stattfindet. Sie befindet sich also bis zu ihrer Deklaration im Quelltext in der sogenannten Temporal Dead Zone.
Redeklaration
Der Versuch, einer bereits deklarierten Konstante einen anderen Wert zuzuweisen, führt wie gesehen immer zu einem Fehler, allerdings erst, wenn der Programmfluss den fehlerhaften Zuweisungsausdruck erreicht. Wird hingegen innerhalb des Gültigkeitsbereichs einer Konstanten derselbe Bezeichner noch einmal bei einer Deklaration verwendet, dann erzeugt dies einen Typfehler zur Compilezeit (Early Error) und das Programm wird gar nicht erst ausgeführt.
// Type Error before execution
const unique = Symbol( );
var unique = false;
Dabei spielt es auch keine Rolle, ob der Bezeichner für eine weitere Deklaration mit const verwendet wird, oder ob damit eine Funktion oder eine Variable deklariert wird, gleich welchen Typs, oder ob ein formaler Parameter einer Funktion denselben Bezeichner besitzt. Das Programm wird beim Erkennen des Fehlers sofort terminiert.
const
immer dann, wenn die Bindung von Bezeichner und Wert einer Variablen über deren Lebensdauer hinweg konstant bleiben soll, es also nicht beabsichtigt ist, der Variable zu einem späteren Zeitpunkt einen anderen Wert zuzuweisen.
Solche Variablen sind nicht sinnlos. Zum einen können sie Berechnungsergebnisse speichern, die im darauffolgenden Programmteil mehrfach benötigt werden. Zum anderen kann es auch die Verständlichkeit des Programms verbessern, wenn eine umfangreiche Berechnung in mehrere Schritte zerlegt wird und die Zwischenergebnisse unter einem Namen zur Verfügung stehen, der ihre Bedeutung deutlich macht.
for (const linkElement of document.querySelector("a[href]")) {
if (linkElement.childElementCount > 0) {
}
}
Die gezeigte for...of-Schleife durchläuft alle Links im Dokument (also <a>
-Elemente mit einem href
-Attribut). Diese werden von der Document-Methode querySelectorAll() mit einem geeigneten Selektor ermittelt.
Die Variable, in der die Schleife das gerade verarbeitete Element ablegt, kann als const deklariert werden, da sie für einen Schleifendurchlauf unverändert bleiben wird.
var
Das Schlüsselwort var bezeichnet den Vater der Variablen. Dabei handelt es sich um die ursprüngliche JavaScript-Anweisung zur Deklaration von Variablen, und sie verhält sich etwas anders als let und const. Eine var
Deklaration, die außerhalb einer Funktion notiert ist, gilt global. Steht sie innerhalb einer Funktion, gilt sie für die ganze Funktion, in der die var
Anweisung notiert ist. Es ist dabei ganz gleich, wo in der Funktion die var
-Anweisung steht, sie könnte auch ganz am Ende stehen. Diesen Vorgang nennt man Hebung (engl. hoisting). Das funktioniert, weil JavaScript Code erst ausführt, nachdem es das vollständige Script eingelesen und zur Ausführung vorbereitet hat.
function test() {
console.log(alter); // gibt undefined aus
console.log(falter); // Bricht das Script mit ReferenceError ab
var alter = 3;
}
test();
Das Script würde zunächst undefined
ausgeben, weil die Variable alter
innerhalb der test()
-Funktion zwar deklariert wurde, aber zum Zeitpunkt der Log-Ausgabe noch kein Wert zugewiesen wurde. Die Deklaration wird gehoben, die Wertzuweisung dagegen nicht. Der Versuch, falter
zu loggen, bricht das Script mit einem ReferenceError ab, weil eine Variable dieses Namens nicht vorhanden ist.
var
-Anweisung notiert ist.function test() {
var alter = 17;
console.log(alter); // gibt 17 aus
console.log(falter); // bricht das Script nicht mehr ab, aber gibt undefined aus
var falter = 92;
console.log(falter); // gibt 92 aus
}
Automatische Deklaration bei Zuweisung
Wie gezeigt, ist die Verwendung einer Variablen als Wert ist ohne Deklaration nicht möglich. Anders ist es bei der Zuweisung. Aus historischen Gründen erlaubt JavaScript eine Zuweisung an eine undeklarierte Variable und deklariert sie im Moment der Zuweisung automatisch, was unangenehme Folgen haben kann, weil diese Deklaration global erfolgt (dazu gleich mehr). Mit JavaScript 5 wurde der strikte Modus eingeführt, der dieses Verhalten abschaltet und der für neue Programme dringend empfohlen ist. Im strikten Modus führt jede Verwendung einer undeklarierten Variable zu einem Script-Abbruch.
Variablen und das globale Objekt
Ein Bestandteil der JavaScript-Laufzeitumgebung ist das Globale Objekt. In einer Browser-Umgebung findet man dieses Objekt in der Variablen window
. Variablen, die auf globaler Ebene mit var
deklariert oder die automatisch deklariert wurden, findet man als Eigenschaften des window
-Objekts wieder.
Bei Variablen, die global mit let
oder const
deklariert wurden, erfolgt kein Eintrag im globalen Objekt.
Scopes - Gültigkeitsbereiche
Wie eingangs erwähnt, wird durch den Ort der Variablendeklaration festgelegt, welche Programmteile die Variable sehen können und wie lange sie existiert. Diese Sichtbarkeit wird durch so genannte Gültigkeitsbereiche (engl. Scopes) geregelt.
Jedem Anweisungsblock, also Codezeilen, die in geschweifte Klammern eingeschlossen sind, ordnet JavaScript einen solchen Gültigkeitsbereich zu. Diese Zuordnung findet zur Laufzeit statt, nicht nur einmal beim Einlesen des Scripts. Wenn Du also eine Funktion schreibst, wird bei jedem Aufruf dieser Funktion ihr Gültigkeitsbereich neu erzeugt. Wenn die Funktion endet, endet auch die Lebensdauer dieses Gültigkeitsbereichs, und alle Variablen, die sich darin befinden, werden gelöscht. (Diese Aussage ist nur bedingt korrekt, es würde aber zu weit führen, an dieser Stelle auf Closures und ihre Auswirkungen einzugehen).
Außerdem gibt es noch den globalen Gültigkeitsbereich, der dann verwendet wird, wenn kein Anweisungsblock begonnen wurde.
Bei Gültigkeitsbereichen gibt es zwei Aspekte zu beachten. Zum einen ihre Sichtbarkeit, zum anderen ihre Lebensdauer.
Stell dir Gültigkeitsbereiche wie einen Stapel Blätter vor - weiße und gelbe. Auf jedem Blatt können Variablennamen und Werte dafür notiert werden. Zu Beginn haben wir nur ein gelbes Blatt - der globale Gültigkeitsbereich.
An jeder Stelle, wo Ihr Programmcode einen Anweisungsblock bildet, wird ein Immer dann, wenn der Programmablauf den Beginn eines Anweisungsblocks passiert, wird eine neues, weißes Blatt auf den Stapel gelegt. Wird eine Funktion aufgerufen, legen wir ein gelbes Papier auf den Stapel.
Wird eine Variable mit let oder const deklariert, wird das auf dem Blatt vermerkt, dass gerade zuoberst liegt. Anders ist es bei einer Deklaration mit var. Dafür wird das oberste gelbe Blatt - ein Funktions-Scope - gesucht, um die Variable darauf zu vermerken. Mit einer Ausnahme: eine var-Deklaration darf eine let- oder const-Deklaration nicht überschreiben. Das ist ein Syntaxfehler, der dazu führt, dass das Script gar nicht erst startet.
Beim Abrufen eines Wertes, der in einer Variablen steht, wird der Stapel von oben nach unten nach dem gewünschten Namen durchsucht. Das klingt aufwändig
Variablendeklarationen mit let oder const erfolgen als neue Zeilen der Tabelle, aber auf dieser neuen Folie. Es sei denn, man deklariert eine Variable, deren Name schon in der Tabelle steht. In diesem Fall wird in der Zeile mit dem vorhandenen Namen ein Stück Papier auf die Folie geklebt, das den Wert aus der unteren Folie verdeckt. Die existierende Variable wird durch die neue Deklaration überlagert.
Und dann gibt es noch den Fall, dass einer Variablen etwas zugewiesen werden soll, die auf einer tiefer liegenden Folie deklariert ist. Nun kommt der Cutter zum Einsatz. In alle Folien, die über der deklarierenden Folie liegen, wird ein Loch geschnitten, so dass auf
Wird der Anweisungsblock verlassen, wird seine Folie entfernt und weggeworfen. Eventuell aufgeklebte Papierchen verschwinden dabei mit, so dass die alten Werte von überlagerten Variablen jetzt wieder sichtbar werden.
Wird ein Anweisungsblock dadurch betreten, dass eine Funktion aufgerufen wird, bekommt die dafür verwendete Folie ein Lesezeichen. Wird nun während der Funktionsausführung eine Variable mit var
deklariert, werden Folien ohne Lesezeichen kurz hochgeblättert, bis das Funktionslesezeichen gefunden ist, und die Variable dort eingetragen.
let a4breite = 210, a4höhe = 297;
let diagonale = berechneDiagonale(a4breite, a4höhe);
console.log('Die Diagonale hat eine Länge von ' + diagonale + ' mm.');
function berechneDiagonale(breite, höhe)
{
quadratsumme = breite * breite + höhe * höhe;
var diagonale = Math.sqrt(quadratsumme);
return diagonale;
}
In diesem Beispiel kommen zwei Gültigkeitsbereiche vor. Zum einen der globale Bereich. In diesem werden die Variablen breite
, höhe
und diagonale
deklariert. Für der Initialisierung der Variablen diagonale
wird die Funktion berechneDiagonale
aufgerufen.
Dieser Aufruf legt eine zweite Folie auf, und es finden drei Deklarationen statt:
a4breite
- dieser Name ist neu, es wird eine neue Zeile erstellt
a4höhe
- ebenfalls neu, es wird eine weitere neue Zeile erstellt
diagonale
-.
diagonale
- auch dieser Name existiert schon, es wird ein weiteres Papierchen aufgeklebt
Name | Erläuterung |
---|---|
breite
|
dieser Name ist neu, es wird eine neue Zeile erstellt |
höhe
|
ebenfalls neu, es wird eine weitere neue Zeile erstellt |
diagonale
|
dieser Name existiert bereits auf der unteren Folie. Die Funktionsfolie bekommt also ein Papierchen aufgeklebt |
Die Parameter breite
und höhe
werden nun noch mit den als Argument übergebenen Werten befüllt, und dann beginnt die Ausführung der Funktion. Das erste, was sie antrifft, ist eine Zuweisung an eine undeklarierte Variable. Da der strikte Modus nicht eingeschaltet wurde, bedeutet das: Alle Folien beiseite legen und auf der globalen Folie einen neuen Eintrag für quadratSumme
erstellen. Darin wird die Summe der Seitenquadrate gespeichert. In der zweiten Zeile findet eine Zuweisung statt. Zunächst wird der zuzuweisende Wert bestimmt, und dafür wird quadratSumme
benötigt. Diese Variable steht auf der untersten Folie und ist nicht überklebt, ihr Wert wird
Das bedeutet, dass man es schon beim Öffnen des ersten Anweisungsblocks mit zwei Gültigkeitsbereichen zu tun hat. Dass ein neuer Gültigkeitsbereich eröffnet wurde, Der Zugriff auf diese Gültigkeitsbereiche erfolgt von i
befindet sich eine Variable in einem Gültigkeitsbereich (engl: Scope). Die bisherigen Beispiele haben Variablen im sogenannten globalen Gültigkeitsbereich erzeugt, das heißt: sie werden deklariert und bleiben vorhanden, bis die HTML Seite, auf der das Script steht, wieder verlassen wird. Eine solche Gültigkeit kann gelegentlich erforderlich sein, in den meisten Fällen ist das aber nicht nötig. Eine globale Gültigkeit bedeutet nämlich auch ein hohes Konfliktpotenzial, sobald man JavaScript-Programme mit mehr als nur einigen Zeilen schreibt. Wären alle Variablen global, müsste man sehr genau Buch führen, welche man wofür verwendet.
let breite = 210, höhe = 297;
let diagonale = berechneDiagonale(breite, höhe);
console.log('Die Diagonale hat eine Länge von ' + diagonale + ' mm.');
function berechneDiagonale(breite, höhe)
{
quadratsumme = breite * breite + höhe * höhe;
diagonale = Math.sqrt(quadratsumme);
return diagonale;
}
Die Funktion benötigt zwei Zwischenergebnisse: quadratsumme und diagonale. Diese deklariert sie nicht, wodurch sie automatisch im globalen Gültigkeitsbereich gesucht und bei Bedarf angelegt werden. Was die Funktion nicht weiß: Es gibt schon eine Variable diagonale
, die sie einfach mal überschreibt. Auf diese Weise entstehen schwer findbare Programmfehler.
Lokaler Gültigkeitsbereich mit var
Um Abhilfe zu schaffen, erzeugt jede Funktion in JavaScript ihren eigenen Gültigkeitsbereich. Er wird erzeugt, wenn die Funktion aufgerufen wird, und alle Variablen, die innerhalb der Funktion deklariert werden, existieren darin. Außerhalb der Funktion sind diese Variablen nicht sichtbar.
var breite = 210, höhe = 297;
var diagonale = berechneDiagonale(breite, höhe);
console.log('Die Diagonale eines A4-Blattes beträgt ' + diagonale + ' mm.');
function berechneDiagonale(breite, höhe)
{
var quadratsumme = breite * breite + höhe * höhe;
var wurzel = Math.sqrt(quadratsumme);
return Math.round(wurzel);
}
Die abgeänderte Funktion deklariert die Variablen, die sie für ihre Arbeit braucht, mit var
. Die so erzeugten Variablen quadratsumme und diagonale werden dadurch im Gültigkeitsbereich der Funktion erzeugt und verschwinden wieder, sobald die Funktion zum Aufrufer zurückkehrt.
So, wie man auch Funktionen ineinander schachteln kann, sind auch die ihnen zugehörigen Gültigkeitsbereiche ineinander verschachtelt. Damit ist gemeint, dass eine Funktion nicht nur die Variablen nutzen kann, die sie selbst deklariert, sondern auch alle Variablen des Gültigkeitsbereichs, in dem sie definiert wurde.
Lokaler Gültigkeitsbereich mit let oder const
Deklarationen mit let
und const
gehen noch einen Schritt weiter. Um Variablen sozusagen punktgenau deklarieren zu können, reicht ein Scope auf Funktionsebene nicht aus. Deswegen gelten let
und const
nur exakt innerhalb des Anweisungsblocks, in dem sie notiert sind.
let quadratSumme = 0;
for (let i=0; i<10; i++) {
const iQuadrat = i * i;
quadratSumme = quadratSumme + iQuadrat
}
console.log('Summe der Quadrate von 1 bis 10 ist ' + quadratSumme);
In diesem Beispiel werden der Zähler i und sein Quadrat nur innerhalb der for
-Anweisung benötigt. Darum wird iQuadrat innerhalb des Anweisungsblocks für for
mit let deklariert. Bei i
liegt ein Sonderfall vor. Die Klammern der for
-Anweisung bilden für let und const einen eigenen Block, und der eigentliche Anweisungsblock der for
-Anweisung ist darin eingeschachtelt.
Dadurch wird im Beispiel mit 3 Gültigkeitsbereichen gearbeitet. iQuadrat
befindet sich im Block-Scope des Anweisungsblocks der for
-Schleife. i
liegt bereits in dessen Eltern-Scope, der von der for
-Anweisung implizit gebildet wurde. Und quadratSumme
ist im globalen Gültigkeitsbereich deklariert (oder im Funktions-Scope, falls das Beispiel in einer Funktion stehen würde).
Überdecken von Variablen
Neue Möglichkeiten schaffen auch neue Probleme. Betrachte dieses Beispiel:
let summe = 0;
for (let i=0; i<10; i++) {
let summe = summe + i;
}
console.log('Die Summe ist ' + summe);
Die Ausgabe ist: "Die Summe ist 0". Der Grund dafür ist, dass im Anweisungsblock irrtümlich die let
-Anweisung verwendet wird, was eine neue Variable erzeugt. Es ist absolut legitim, in einem Gültigkeitsbereich Variablen zu deklarieren, die genauso heißen wie Variablen, die in einem weiter außen liegenden Gültigkeitsbereich deklariert wurden. Die weiter innen deklarierten Variablen verdecken dann die äußeren und machen sie unzugänglich.
Dieses Verhalten ist gewollt und auch wünschenswert. Man möchte ja gerade erreichen, dass man bei der Verwendung von lokalen Variablen unabhängig von den übergeordneten Gültigkeitsbereichen ist. Variablenzugriff aus dem aktuellen Gültigkeitsbereich hinaus - vor allem aus dem Funktions-Gültigkeitsbereich - sollten stets gut geplant sein und nur mit gutem Grund stattfinden.
Zugriff auf überdeckte Variablen
Grundsätzlich gilt: überdeckte Variablen sind überdeckt und nicht erreichbar.
Es gibt aber Variablen oder Schnittstellen, die vom Browser im globalen Gültigkeitsbereich bereitgestellt werden und relativ gewöhnliche Namen tragen, wie location
oder document
. Wenn man diese Schnittstellen nicht braucht, ist man leicht versucht, solche Namen auch für lokale Variablen zu verwenden. Schlimmer noch, es könnte passieren, dass eine neue Schnittstelle eingeführt wird, unter einem Namen, den man bisher für frei hielt.
Um dennoch auf solche globalen Objekte zugreifen zu können, stellt JavaScript ein spezielles Objekt bereit, das die globalen Variablen als Objekteigenschaft zur Verfügung stellt. Dieses Objekt findet sich im Browser in der globalen Variablen window
. Es ist zwar möglich, aber überhaupt keine gute Idee, eine lokale Variable dieses Namens zu erzeugen.
Wenn du im Browser einen Worker (Web oder Service Worker) erzeugst, bekommt er einen eigenen, unabhängigen globalen Gültigkeitsbereich. Diesen erreicht man über die globale Variable self
. Falls man Code hat, der sowohl im normalen Browser-Umfeld wie auch in einem Worker laufen soll, wäre es unpraktisch, zwischen window
und self
unterscheiden zu müssen. Deshalb wird self
auch als Alias von window
bereitgestellt.
In node.js, einer anderen JavaScript-Ablaufumgebung, heißt diese spezielle Variable global
.
var
deklariert, finden sich auch als Eigenschaften des globalen Objekts wieder. Aber eine mit let
oder const
deklarierte Variable ist über das globale Objekt nicht erreichbar, auch nicht, wenn die Deklaration im globalen Gültigkeitsbereich stattfand.Und was tut man, wenn man unbedingt auf das globale Objekt zugreifen muss, aber window
oder self
nicht erreichbar sind? Vor Einführung des strikten Modus gab es dafür einen Trick. Man rief eine Funktion auf und verwendete darin die spezielle Variable this
. Im strikten Modus funktioniert das nicht, dort enthält this
entweder null
oder ein Objekt, für das die Funktion als Methode aufgerufen wurde.
Die Antwort heißt: Wenn du deinen Weg verbaut hast, ist er verbaut. Gestalte deinen Code um. Verwende keine globale Variable namens window
oder self
.
doppelt?
Scope und Hebung
var
ist das klassische Javascript Syntaxelement zum Definieren lokaler Variablen. Die Semantik von var
-Variablen unterscheidet sich von der gewohnten Semantik in Sprachen wie C oder Java dahingehend, dass solche Variablen keinen Block-Scope kennen. Was mit var
vereinbart wird, wird vom JavaScript-Interpreter so behandelt, als hätte diese Vereinbarung am Beginn des Script-Blocks bzw. der Funktion stattgefunden, worin die var-Deklaration steht. Diese Verschiebung des Deklarationspunktes nennt man Hebung (hoisting).
testVar = "abc";
function test() {
testVar = 17;
alert(testVar); // gibt "17" aus
if (5 > 1) {
var testVar = 3;
}
}
test();
alert(testVar); // gibt "abc" aus, testVar wurde nicht überschrieben
Anders verhält sich let. Dieses Schlüsselwort ist mit ECMAScript2016 eingeführt worden, um die in anderen Sprachen bekannte Scope-Semantik auch in ECMAScript nutzen zu können. Mit let definierte Variablen unterliegen nicht der Hebung, und gelten nur in dem Anweisungsblock, in dem sie definiert wurden.
Gültigkeitsbereiche (alter Artikel)
Wir haben Variablen bisher unabhängig von dem Umfeld betrachtet, in dem sie verwendet werden. Das liegt vor allem daran, dass dieser Artikel ganz am Anfang der JavaScript-Artikelreihe steht und viele Konzepte, die zum Verständnis von Gültigkeitsbereichen erforderlich sind, noch gar nicht bekannt sind. Deshalb kann es an dieser Stelle nur einen kurzen Überblick geben.
Grundsätzlich kennt JavaScript vier Arten von Gültigkeitsbereichen oder Scopes. Diese Gültigkeitsbereiche werden ausschließlich auf Basis des JavaScript-Programmtextes gebildet, den man verfasst. Sie hängen nicht davon ab, wie du deine erstellten Programmbausteine zur Ablaufzeit miteinander kommunizieren lassen.
- Global Scope
- Solange du keine Funktionen schreibst oder Anweisungsblöcke bildest, befinden sie sich im Global Scope. Variablen, die darin deklariert werden, sind überall im Programm sichtbar. Den Global Scope gibt es naturgemäß nur einmal.
- Module Scope
- Dies ist ein Sonderfall des Global Scope für Module nach dem ECMAScript 2015 Standard. Deklarationen auf oberster Ebene, die in einem solchen Modul stattfinden, sind nur innerhalb dieses Modules sichtbar. Jedes Modul hat seinen eigenen Module Scope.
- Function Scope
- Funktionen sind ein Sprachmittel, um wiederverwendbaren Programmteile zu erzeugen. Dazu gehört auch, dass diese Programmteile über eigene Variablen verfügen, die bei jeder Verwendung der Funktion neu bereitgestellt werden. Variablen, die du in einer Funktion deklarierst, sind deshalb nur innerhalb dieser Funktion sichtbar.
- Es ist möglich, innerhalb einer Funktion weitere Funktionen zu erstellen. Die Variablen der äußeren Funktion sind auch in den inneren Funktionen sichtbar und verwendbar.
- Einer Funktion wird jedesmal, wenn sie aufgerufen wird, für ihren eigenen Function Scope Speicherplatz zugewiesen. Endet der Aufruf, wird seine Verbindung zu diesem Speicherbereich wieder getrennt und die Speicherverwaltung von JavaScript kann ihn löschen.
- Block Scope
- JavaScript-Anweisungen lassen sich zu Anweisungsblöcken zusammenfassen. Das benötigt man für die Ablaufsteuerung im Programm. Ursprünglich hat JavaScript für Anweisungsblöcke keinen eigenen Scope gebildet. Deswegen liegen
var
-Deklarationen niemals in einem Block Scope, sondern gehören zum Function-, Module- oder Global-Scope. In ECMAScript 2105 (ES6) kam der Block-Scope hinzu. Eine Variable, die mitconst
oderlet
deklariert wird, befindet sich im Block-Scope und verliert ihre Gültigkeit, sobald der zugehörige Anweisungsblock endet.
Da der Scope von Modulen, Funktionen und Blöcken durch den Ort bestimmt wird, an dem diese Programmteile aufgeschrieben sind, spricht man hier auch von lokalen Scopes.
Variablen, Namen und Bindung
Die Existenz mehrerer Scopes, die dazu auch noch ineinander geschachtelt sein können, wirft mehrere Fragen auf. Eine davon ist: Was geschieht, wenn eine Variable in mehr als einem Gültigkeitsbereich deklariert wurde?
Um das zu beantworten, muss man zwischen Namen und Variablen unterscheiden. Wenn man im globalen Scope eine Variable xyz
deklariert, dann gibt es in dem Speicherbereich, der zum globalen Scope gehört, eine Variable, und JavaScript ordnet ihr den Namen xyz
zu. Das ist die Bindung des Namens an die Variable.
Wenn du eine Funktion erstellst und zu Beginn eine Variable xyz
deklarierst, dann machst du JavaScript bekannt, dass es in dieser Funktion den Namen xyz einer Variablen mit Function Scope zuordnen soll. In dem Moment, wo die Funktion aufgerufen wird, reserviert JavaScript Speicherplatz und schafft damit Platz für die Variablen, die für den Function Scope deklariert wurden.
Während die Funktion läuft, gibt es für den Namen xyz
zwei Variablen. Eine davon liegt im Global Scope, ist aber während der Funktionsausführung nicht sichtbar, weil ihr Name innerhalb der Funktion an eine lokale Variable gebunden wurde. Programmcode, der außerhalb dieser Funktion aufgeschrieben ist, verwendet diese Bindung nicht.
Eine tiefergehende Diskussion dieses Thema muss dem Artikel über Funktionen vorbehalten bleiben. Auf eine Frage soll aber noch eingegangen werden: Was ist, wenn ich in einem lokalen Scope einen Namen definiert habe, der einen Namen im globalen Scope überdeckt - aber trotzdem den Bedarf habe, auf die globale Variable zuzugreifen?
Globaler Scope - Globales Objekt
Der Begriff des Objekts ist bisher noch nicht richtig definiert worden. Merken Sie sich einstweilen nur, dass ein Objekt ein Speicherbereich ist, in dem Sie Werte unter einem Namen ablegen können. Die so erstellten Einträge in diesem Speicherbereich nennen sich Eigenschaften.
Objekteigenschaften und Variablen sind sich also ziemlich ähnlich. Der Hauptunterschied ist, dass JavaScript einen Namen an Hand des Scopes automatisch an eine Variable bindet. Um auf eine Eigenschaft zuzugreifen, müssen Sie das Objekt, in dem gesucht werden soll, ausdrücklich angeben.
Variablen, die Sie im globalen Scope mit var
deklarieren, werden automatisch als Eigenschaften in einem so genannten globalen Objekt bereitgestellt. Sie können das globale Objekt verwenden, um diese Variablen jederzeit zu erreichen. Der Name für dieses globale Objekt ist unterschiedlich, je nachdem, wo Sie JavaScript ausführen.
var
deklariert.JavaScript in einem Dokument eines Webbrowsers verwendet den Namen window
für das globale Objekt. Außer Ihren selbst deklarierten globalen Variablen befinden sich dort buchstäblich hunderte vom Browser vordefinierte Einträge. Hinzu kommen weitere globale Variablen aus JavaScript-Bibliotheken, die Sie vielleicht nutzen möchten. Der globale Scope ist ein Kollision, die nur darauf wartet, zu passieren, deshalb sollten Sie alles tun, um ihre eigenen Variablen dort herauszuhalten. Wir werden in späteren Artikeln darauf eingehen, wie man dafür vorzugehen hat.
Sie können aus ihrem Dokument-JavaScript noch weitere JavaScript-Umgebungen starten, sogenannte Web Worker. In solchen Umgebungen ist das angezeigte Dokument nicht zugänglich, und das globale Objekt in einem Worker findet sich unter dem Namen self
.
Und schließlich gibt es ein beliebtes Tool, um Serverprogramme in JavaScript schreiben zu können, node.js. Dieses Programm verwendet die JavaScript-Engine „V8“ von Google. In einem node.js-Programm gibt es ebenfalls kein HTML-Dokument, dass gerade angezeigt wird, und kein window-Objekt. Das globale Objekt in node.js nennt sich global
.
Für Programmierer, die eine JavaScript-Funktion erstellen möchten, die in mehr als einer dieser Umgebungen läuft und Werte aus dem globalen Objekt benötigt, ist diese Namensvielfalt ein Problem. Sie müssen entweder drei Versionen ihrer Funktion bereitstellen, oder irgendwie erkennen, in welcher Umgebung die Funktion läuft. Um das Problem zu beheben, wurde ein einheitlicher Zugriff auf das globale Objekt spezifiziert: die Variable globalThis
Es wäre auf den ersten Blick praktischer gewesen, statt eines neuen Begriffs die Variablen window
, global
und self
in allen Ausführungskontexten gleichermaßen bereitzustellen, aber das hätte mit Sicherheit alten Code kaputt gemacht, der nicht erwartet, diese Variablen vorzufinden.
Abzuraten ist von der früher gezeigten Idee, eine Funktion aufzurufen und darin die Kontextvariable this
auszulesen. Außerhalb des strict mode funktioniert das, this
enthält dann das globale Objekt. Aber moderner JavaScript-Code sollte immer im strengen Modus (strict mode) geschrieben werden, und darin funktioniert diese Methode nicht mehr. Verwenden Sie globalThis
.
- Hauptartikel: JavaScript/Scope
umfangreicher Hintergrundartikel zum tieferen Verständnis
Empfehlungen für die Praxis
- Verwende den strict mode, um durch Tippfehler versehentlich erzeugte globale Variablen auszuschließen.
- Scope (Gültigkeit):
Benutze Variablen – soweit möglich – lokal und deklariere sie auch dort. So wird dein Script übersichtlicher und leichter zu debuggen.- Deklariere globale Variablen am Anfang des Scripts mit
-
const
für unveränderliche Konstanten -
let
für Variablen
-
- Halte den globalen Namensraum sauber. Globale Variablen sind dank verschiedener Kapselungs-Techniken seltener erforderlich, als man glaubt, aber wenn es gar nicht anders geht, dann solltest du deine Variablen in einem Namensraum-Objekt zusammenfassen. In dessen Eigenschaften können globale Informationen für dein Projekt abgelegt werden.
- lokale Variablen kannst du mit const oder let deklarieren.
- Deklariere globale Variablen am Anfang des Scripts mit
- Variablennamen
Benutze sprechende Namen, d. h. sinnvolle Bezeichnungen, die sich später zurückverfolgen lassen.ausgabe = breite * höhe;
ist besser alsa = b * h;
- Beachte die Regeln für selbstvergebene Namen, z.B:
- Variablen sind case-sensitive, also achte immer auf Groß-und Kleinschreibung.
- CamelCase
Besser lesbar ist das so genannte CamelCase, in dem die ersten Buchstaben der einzelnen Bestandteile des Namens groß geschrieben werden. - Achte bei den Namen für deine eigenen Variablen und Funktionen aber darauf, dass es keine Namenskollisionen mit Reservierten Wörter gibt.
testVar
ist lokal zur Funktiontest()
, weil das Hoisting dafür sorgt, dass die Deklaration aus dem if heraus an den Anfang gezogen wird.