Wie angedroht wird hier mein kleiner Guide entstehen, in dem es um die die Grundlagen der Programmierung von Scripten für D2NT entstehen.
Da ich generell momentan wenig Zeit habe, werde ich nach und nach editieren, je nachdem wie ich Zeit und Lust habe.
Die Struktur ist noch alles andere als Fest und wird eventuell noch drastisch geändert.
Grundsätzliches
Da ich immer wieder nach sehr grundlegenden Zusammenhängen gefragt werde, fand ich ich mal angebracht, diese einfach mal allgemein zu erläutern, um einigen zukünftigen Fragen vorzubeugen.
Der folgende Guide beschäftigt sich mit den Grundlagen der Programmierung in und um D2NT und richtet sich somit in erster Linie an interessierte Einsteiger.
Dabei werde auf niedrigem Niveau starten (Plattdeutsch: from scratch), wobei ich trotzdem versuche, beim Schwerpunkt D2NT zu bleiben und nicht zu sehr in die Theorie abzudriften, auch wenn man um ein paar Dinge einfach nicht herum kommt.
Falls hier in der Einleitung Begriffe auftauchen, die unbekannt sind:
Nicht verzweifeln, ich werde später darauf eingehen.
Ich sollte an dieser Stelle vielleicht anmerken, dass ich kein Informatiker bin, sondern lediglich das Vergnügen hatte, mich zwei Semester lang mit den Grundlagen der Programmierung in C++ zu beschäftigen.
Die Sprachen sind bezüglich der Syntax verwandt, wobei C++ sehr viel komplexer ist, aber das wollen wir ja hier auch nicht lernen.
Trotzdem kann es deshalb sowohl vorkommen, dass ich sachliche Fehler einbaue, mich vor allem aber von den Begrifflichkeiten her sehr an C++ orientiere, sodass sich Leuten die von Java bzw. JavaScript her kommen eventuell an der ein oder anderen Stelle die Nackenhaare aufstellen. In beiden Fällen nehme ich dazu gerne Hinweise per PM entgegen.
Ich lege ausserdem Wert auf eine halbwegs solide Rechtschreibung, denn nur das lässt sich hinterher auch angenehm lesen. Ich finde es gibt nichts schlimmeres, als wenn man einen Satz auch nach zehnmaligem lesen nicht versteht, weil sich dieser jeder sprachlichen Norm entzieht.
Da ich aber zu allem Überfluss auch nur angehender Ingeneur bin, habe ich es selber nicht so mit korrekter Rechtschreibung.
Darum bitte ich auch um Hinweise auf Rechtschreibfehler meinerseits, sowie ungünstig formulierte oder generell unverständliche Sätze, wobei mir hier auch eine PM mit einem Hinweis wünsche, damit das Topic sauber bleibt.
Vorraussetzungen für Interessierte:
oder irgend ein vergleichbarer Editor, der Syntaxhighlighting für JavaScript unterstützt- Interesse
- Ein wacher Verstand
Hinweis zu Notepad++:
Um in Notepad++ das Syntaxhighlighting für JavaScript, für die D2NT typischen Endungen, zu aktivieren, müsst ihr folgendes tun:
- Notepad++ starten
- Einstellungen --> Stile
- Links unter "Sprache" JavaScript auswählen
- In der zweiten Box von links unten im Feld "Benutzer-Erw." folgendes einfügen: ntl ntj nip (jeweils durch ein Leerzeichen getrennt)
- "Speichern" Button
Weiterführende Links:
Hier ein bisschen Futter für diejenigen, die nicht genug bekommen können oder denen meine Kurzbeschreibungen nicht ausreichen.

Eine sehr viel umfangreichere, englischsprachige Einführung in JavaScript, dessen Lektüre ich wärmstens empfehlen kann.

Eine tolle Referenz für JavaScript Standardfunktionenm, sowie eine recht ausführliche Beschreibung der Grundlagen.

D2NT und D2BS sind sich in vielen Punkten ähnlich, darum kann die D2BS in einigen Punkten Aufschluss über die Umsetzung in D2NT geben.
Aber immer bedenken, dass nicht alles was man dort findet, auch in D2NT so umgesetzt ist.
1. Der Einstieg
Wie viele sicherlich schon bemerkt haben, setzt sich D2NT aus einer vielzahl verschiedener Scripte zusammen. Diese sind nichts anderes als Textdateien, die Quellcode enthalten.
Dieser Quellcode ist für Einsteiger auf den ersten Blick erstmal ein ziemlicher Schlag und will nicht so richtig Sinn ergeben.
Aber keine Angst: Das kann man lernen und den Einstieg dazu versuche ich hier mit euch zu machen.
Aber was ist eigentlich Quelltext?
Als Quelltext, gerne auch Quellcode (Plattdeutsch: Sourcecode), bezeichnet man Dokumente, die Programme oder Programmteile in uncompilierter Form in irgendeiner Art von Programmiersprache enthalten.
Darin ist festgelegt, wie ein Programm abläuft oder einfacher gesagt was ein Programm macht.
Damit ein Programm nun aber auch tatsächlich laufen kann, braucht es natürlich einen Rechner, auf dem das Programm ausgeführt wird.
Nun liegt aber der Quellcode in einer Programmiersprache, beispielsweise JavaScript vor; dummerweise spricht der Rechner aber kein Javascript.
Deshalb muss jeder Quellcode zunächst in eine Sprache übersetzt werden, die der Rechner versteht.
Und das ist Binärcode, also Einsen und Nullen. Um also aus dem Quellcode ein ausführbares Programm zu machen, muss ein Übersetzter her, der z.B. JavaScript in Binärcode übersetzen kann.
Dieses Übersetzen bezeichnet man als compilieren, das Programm was die Übersetzung übernimmt ist dementsprechend der Compiler.
Wie das genau funktioniert soll uns nicht weiter interessieren, es reicht wenn wir wissen, dass unsere D2NT API, also unsere Laufzeitumgebung, alle unsere Scripte zunächst in Binärcode umwandelt und sie dann ausführt.
Was ist eine Programmiersprache?
Nun ist der Begriff ja vorher schon sehr häufig gefallen, aber so richtig erklärt wurde die bedeutung nicht - Zeit dies zu ändern.
Die Sprache, in der alle D2NT Scripte verfasst sind, heisst JavaScript.
Soweit nichts neues, habe ich schließlich schon mehrfach erwähnt, aber was ist denn nun JavaScript?
Eine Programmiersprache im allgemeinen ist eine künstlich geschaffene Sprache, die es erlaubt, (komplexe) logische Zusammenhänge möglichst kompakt und für einen Compiler verarbeitbar - also gut in Binärcode übersetzbar - auszudrücken.
Im Prinzip ist das sehr vergleichbar mit der Sprache die wir sprechen, sei es nun Deutsch oder Englisch. Es gibt bestimmte Wörter, die alle eigene Bedeutungen haben, sowie gewisse Regeln, wie man verschiedene Wörter verknüpft.
Trotzdem gibt es einen entscheidenden Unterschied:
Anders als bei gesprochenen Sprachen, bei denen die Formulierung nicht immer ganz der Norm entsprechen muss (Anm.: Wobei einige hier diese Freiheit wirklich bis zum Exzess bzw. bis zur Unlesbarkeit ausnutzen!
Der Schlüssebegriff dazu ist Syntax.
Die Syntax gibt vor, wie etwas ausgedrückt zu sein hat. Und den letzten Teil sollte man sich zu Herzen nehmen.
Es reicht beim Programmieren nicht, Dinge so zu schreiben, dass sie ungefähr der Syntax entsprechen, es muss alles in allem syntaktisch korrekt sein, ohne Ausnahme.
Ist dies nicht der Fall, meldet sich auch direkt der Compiler zu Wort, wenn wir versuchen, ein Programm mit Syntaxfehlern auszuführen, weil unser Programm vor dem Compilieren immer erst auf syntaktische Fehler untersucht wird.
Das Compilieren wird dann abgebrochen und wir bekommen eine Fehlermeldung. Aus genau diesem Grund sind Syntaxfehler auch nicht so extrem schlimm, weil man den Fehler immer direkt sehen kann, bevor das Programm überhaupt ausgeführt wird.
Schlimmer sind da Logik- bzw- Denkfehler, welche auftreten, wenn ein Programm zwar syntaktisch richtig ist, aber Inhaltlich falsch ist- auf ein paar typische Denkfehler werden wir später noch eingehen.
Syntaxfehler kennt jeder, der schonmal versucht hat, Änderungen an einem Script vorzunehmen, ohne auch nur die leiseste Ahnung zu haben, was er da eigentlich tut - aber das ändern wir jetzt schließlich.
Sogesehen ist der Einstieg in JavaScript vielleicht zunächst vergleichbar mit dem allseits geliebte Vokabel-Lernen aus der Schule. Mit dem Unterschied, dass man mit ein paar wenigen Begriffen schon einiges erreichen kann.
Die "Vokabeln" bestehen hierbei auch eher aus bestimmten Schlüsselbegriffen und der Art und Weise, wie man einige grundsätzlich Dinge umsetzt (Anm.: Gemeint sind Schleifenkonstrukte, Aufbau von Funktionen und Klassen etc.).
Diese Schlüsselbegriffe sind es übrigens auch, die durch das sogenannte Syntaxhighlighting in einem entsprechenden Editor hervorgehoben werden, was ein enormes Plus in Sachen Übersichtlichkeit mit sich bringt und somit absolut zu empfehlen ist.
Sie werden in den folgenden Beispielen auf diese Weise hervorgehoben:
Code:
[COLOR=Navy][B][I]Schlüsselbegriff[/I][/B][/COLOR]
Was ist in Sachen Syntax allgemein zu beachten?
Im folgenden tauchen eventuell einige unbekannte Begriffe auf, darauf wird später genauer eingegangen werden.
Nun zu den Grundregeln der JavaScript Syntax:
Anweisungen
Der wohl häufigst vorkommende Vertreter: Das Semikolon (";"):
Anweisungen enden immer mit einem Semikolon!
Beispiel:
Code:
[COLOR=Navy][B][I]var[/I][/B][/COLOR] a = [COLOR=Red]1[/COLOR]; [COLOR=Navy][B][I]var[/I][/B][/COLOR] b = [COLOR=Red]2[/COLOR]; [COLOR=Green]// Weil Anweisungen immer mit einem Semikolon enden und nicht etwa mit jeder Zeile, kann man theoretisch sein komplettes Programm in eine Zeile schreiben (Was man natürlich nicht macht!)[/COLOR] [COLOR=Navy][B][I]var[/I][/B][/COLOR] a = [COLOR=Red]1[/COLOR]; [COLOR=Navy][B][I]var[/I][/B][/COLOR] b = [COLOR=Red]2[/COLOR];
Jede Blockanweisung wird mit einem (!) Tabulatorsprung eingerückt. Richtiges Einrücken gehört zum guten Stil und erhöht die Übersichtlichkeit enorm. Anweisungsblöcke sind typischerweise durch geschweifte Klammern gekennzeichnet.
Beispiel:
Code:
[COLOR=Green]// Anweisungsblock A[/COLOR]
{
[COLOR=Green]// Anweisungsblock B[/COLOR]
{
[COLOR=Green]// Anweisungsblock C[/COLOR]
{
}
[COLOR=Green]// Anweisungsblock D[/COLOR]
{
}
}
}
In Notepad++ funktioniert das übrigens auch wunderbar für mehrere Zeilen, indem diese vorher einfach mit der Maus markiert werden. Bei gedrückter Strg-Taste kann man ausserdem mit der Tabulator Taste Tabulator Sprünge rückgängig machen, also sozusagen nach links einrücken, wobei auch dies mittels Markieren mehrzeilig funktioniert.
Kommentare
Neben ordentlichem Einrücken gehört es auch zum guten Programmierstil, den eigenen Quelltext ordentlich zu kommentieren.
Alles was als Kommentar gekennzeichnet ist, wird vom Compiler ignoriert und somit nicht mitübersetzt.
Und das ganze funktioniert so:
Code:
[COLOR=Green]// Dies ist ein einzeiliger Kommentar /* Das ist ein mehrzeiliger Kommentar */[/COLOR]
Denn typischerweise weiss man nach einigen Wochen selber nicht mehr so genau, was man an der ein oder anderen Stelle gemacht hat und dann helfen einem Kommentare weiter, um möglichst schnell wieder Zugang zur Materie zu bekommen.
Kommentare werden durch das Syntaxhighlighting grün hervorgehoben, weshalb ich dies auch für meine Beispiele übernehme, dient es doch dem Auseinanderhalten von Quellcode und Kommentar.
Operatoren
Operatoren sind elementare Schlüsselbegriffe, die allgemein dazu dienen, zwischen zwei Elementen (wie auch immer diese Aussehen mögen) zu vermitteln.
Klingt erstmal sehr abstrakt, ist aber recht leicht verständlich, wenn man einfach mal ein paar Operatoren nennt:
Code:
[COLOR=Green]// Alte Verwandte aus der Mathematik[/COLOR] +, -, /, *, % [COLOR=Green]// Und noch ein paar Operatoren[/COLOR] =, +=, -=, /=, *=, ++, --, (), [], ?:, "," [COLOR=Green]// Vergleichsoperatoren[/COLOR] ==, !=, <=, >= [COLOR=Green]// Logische Operatoren[/COLOR] &&, ||, !
// TODO: Weiteres zum Einstieg?
2. Einfache Variablen
Wir steigen direkt mit einem Überaus wichtigen Thema ein - den Variablen.
Ganz ähnlich wie in der Mathematik sind Variablen in der Programmierung von uns festgelegte "Container", welche Werte - welcher Form auch immer diese einzuordnen sind - repräsentieren können. Ganz analog zur Mathematik haben Variablen Namen bzw. Bezeichner und Werte.
In der Programmierung kommt nun aber ein kleines Detail hinzu:
Weil die Art des Wertes der Variable verschieden sein kann, muss bekannt sein, welche Art von Wert eine Variable haben soll. Und damit kommen wir direkt zum ersten Thema:
Datentypen
Von welcher Art der Wert einer Variablen ist, spiegelt sich in ihrem Datentyp wieder. Denn weil die Variable zur Programmlaufzeit in den Arbeitsspeicher geladen wird, muss bekannt sein, wieviel Speicherplatz diese einnimmt - und genau das verbirgt sich hinter ihrem Datentyp, jeder Datentyp hat benötigt eine spezifische Menge an Speicherplatz.
Auf die einzelnen Größen der verschiedenen Datentypen werde ich hier nicht eingehen, da dies für die D2NT Programmierung praktisch keine Rolle spielt.
Häufig vorkommende Datentypen sind z.B. int(eger), char(acter), bool(ean), double oder string, aber dazu später mehr.
Deklaration und Initialisierung von Variablen
Wer schonmal in einer Sprache wie Java oder C++ programmiert hat, weiss, das eine Variable immer zunächst deklariert, also bekanntgemacht werden muss, bevor man sie verwenden bzw. ihr einen Wert zuweisen kann. In den oben genannten Sprachen schreibt man das dann beispielsweise so:
Code:
[COLOR=Blue][B]int[/B][/COLOR] zahl;
In JavaScript sieht die Sache etwas anders aus...
Variablen werden zwar genauso deklariert, allerdings taucht statt des Datentyps einfach nur der Schlüsselbegriff var auf. Das soll aber nicht heissen, dass Variablen in Javascript keinen Datentyp haben.
Vielmehr ist es so, dass bei der Zuweisung eines konkreten Wertes gerprüft wird, von welchem Datentyp der zugewiesene Wert ist. Folglich ist die Variable vom Datentyp, des ihr zugewiesenen Wertes, was aber erst bei der Zuweisung entschieden wird.
Somit geträt der Datentyp einer Variable manchmal etwas in den hintergrund, man sollte dennoch wissen, von welchem Datentyp die eigenen Variablen sind.
Soweit so gut, Variablen deklariert man also mit dem Schlüsselwort var, gefolgt von einem Bezeichner. Wie kann man den Variablen aber nun einen konkreten Wert zuweisen, sie also initialisieren?
Die Antwort ist simpel: mit dem Zuweisungsoperator (=)!
Für das obige Beispiel könnte das so aussehen:
Code:
[COLOR=Green] // Deklaration einer Variablen[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] zahl; zahl = [COLOR=Red]42[/COLOR];[COLOR=Green] // Der Variablen wird der Wert 42 zugewiesen, es handelt sich somit nun um eine Integer Variable (ganzzahliger Datentyp)[/COLOR] [COLOR=Green] // Wir deklarieren eine weitere Variable...[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] nochEineZahl = [COLOR=Red]18[/COLOR];[COLOR=Green] // ...und initialisieren sie im selben Schritt mit dem Wert 18[/COLOR] [COLOR=Green] // Das schreit nach einer kleinen Rechnung[/COLOR] :) [COLOR=Green]// Wir deklarieren noch eine Variable[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] summe; summe = zahl + nochEineZahl;[COLOR=Green] // Wir weisen dieser Variable die Summe aus zahl und nochEineZahl zu, also 42+18, wobei immer zuerst der zuzuweisende Teil berechnet wird, bevor der alte Wert der Variablen überschrieben wird // Somit hat die Variable summe nun den Wert 60[/COLOR]
Code:
[COLOR=Navy][I][B]var[/B][/I][/COLOR] zahl = [COLOR=Red]42[/COLOR], nochEineZahl = [COLOR=Red]18[/COLOR], summe = [COLOR=Red]5[/COLOR]; [COLOR=Green]// Deklaration und Initialisierung mehrere Variablen in einer Zeile, durch Kommata separiert, womit man sich zweimal das Schlüsselwort var spart[/COLOR] [COLOR=Green]// Wie man sieht habe ich der Variablen summe nun auch einen Startwert verpasst, nun addieren wir auf diesen Startwert die Werte der Variablen zahl und nochEineZahl[/COLOR] summe += zahl + nochEineZahl;[COLOR=Green] // Summe hat nun den Wert 65[/COLOR] [COLOR=Green]// Der += Operator ist eine Kurzschreibweise: a += b entspricht dabei dem Ausdruck a = a + b[/COLOR]
Die oben verwendete Kurzschreibweise += gibt es auch noch für die anderen standard Rechenoperationen:
Code:
a += b <=> a = a + b a -= b <=> a = a - b a *= b <=> a = a * b a /= b <=> a = a / b [COLOR=Green]// Ausserdem:[/COLOR] a++ <=> a = a + 1 a-- <=> a = a - 1
Code:
[COLOR=Green] // Datentyp[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myInteger = [COLOR=Red]42[/COLOR]; [COLOR=Green]// Integer - Ganzzahl[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myDouble = [COLOR=Red]3.14159265[/COLOR]; [COLOR=Green] // Double - Gleitkomma Wert; eigentlich eher Gleitpunkt Wert, denn die Dezimaltrennung erfolgt durch einen Punkt wie in der englischen Schreibweise üblich und nicht wie im Deutschen durch ein Komma[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myBool = [COLOR=Navy][B][I]true[/I][/B][/COLOR]; [COLOR=Green]// Boolean - Schaltvariable; Mögliche Werte: true, false[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myString = [COLOR=DimGray]"Text"[/COLOR]; [COLOR=Green] // String - Zeichenkette (eigentlich kein einfacher Datentyp);[/COLOR]
Implizite und Explizite Typumwandlungen
Die Überschrift klingt direkt mal wieder etwas haarstreubend, was sich dahinter verbirgt ist aber eigentlich nicht weiter schlimm.
Damit gemeint ist eine Konvertierung eines Datentyps in einen anderen, was man gemeinhin als Cast bezeichnet.
Was bedeutet implizit Casten?
Ein Cast ist immer dann implizit, wenn es vom Compiler selbst durchgeführt wird. Implizite Casts programmieren wir also nicht direkt ein, sie finden aber trotzdem statt.
Das geschieht zum Beispiel immer dann, wenn wir mit Zahlen Rechnen, die von unterschiedlichen Datentypen sind, sehr häufig auch im Zusammenhang mit Zeichenketten.
Hier mal ein Beispiel für ein implizites Cast:
Code:
[COLOR=Navy][I][B]var[/B][/I][/COLOR] myInteger = [COLOR=Red]5[/COLOR]; [COLOR=Green] // Ganzzahl Variable, initialisiert mit dem Wert 5[/COLOR] [COLOR=Navy][I][B]var [/B][/I][/COLOR]myDouble =[COLOR=Red] 2.5[/COLOR]; [COLOR=Green]// Fließkomma Variable, initialisiert mit dem Wert 2,5[/COLOR] [COLOR=Green]// Nun Teilen wir die beiden Zahlen durcheinander[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myResult = myInteger / myDouble; [COLOR=Green]// myResult hat nun den Wert 2[/COLOR]
Der Compiler castet nämlich die Integer Variable myInteger nach double, um sie danach durch die double Variable myDouble teilen zu können, womit effektiv 5.0 durch 2.5 geteilt wird.
Wir merken uns also: 5.0 und 5 sind nicht dasselbe, weil unterschiedliche Datentypen dahinter stehen.
Ich hoffe es liegt auf der Hand, warum die Integer Variable in eine Double Variable umgewandelt wird und nicht umgekehrt; Wenn man eine Fließkomma Zahl in eine Ganzzahl umwandelt kommt es zu Datenverlust, die Nachkommastellen gehen dabei verloren.
Implizite Casts finden aber beispielsweise auch immer dann statt, wenn ihr numerische Werte ausgebt. Die Ausgabe Funktion akzeptiert nämlich nur Zeichenketten, darum werden sämtliche numerischen Werte vor der Ausgabe jeweils in eine Zeichenkette umgewandelt, also nach string gecastet.
Auch dies geschieht ganz automatisch, ohne das wir entsprechende Anweisungen einprogrammieren müssten.
Wann ist ein Cast explizit?
Explizite Casts zeichnen sich dadurch aus, dass wir sie ganz bewusst mit einer Anweisung durchführen.
Somit können wir selbst bestimmen, in welcher Form gecastet wird, sodass sich auch Casts ergeben können, die nur bedingt sinnvoll sind.
Zum Beispiel sowas:
Code:
[COLOR=Navy][I][B]var[/B][/I][/COLOR] myDouble = [COLOR=Red]2.5[/COLOR]; [COLOR=Green] // Fließkomma Variable, initialisiert mit dem Wert 2,5 // Wir wandeln diese Variable nun explizit in eine Ganzzahl um und initialisieren mit dem Ergebnis die Variable myResult:[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myResult = parseInt(myDouble); [COLOR=Green]// Welchen Wert hat myResult nun?[/COLOR] [Spoiler] [COLOR=Green]/* Die Antwort lautet: 2 Bei der Umwandlung werden die Nachkommastellen einfach abgeschnitten. Es wird NICHT gerundet! */[/COLOR] [/Spoiler]
Zum Beispiel, wenn man numerische Ausdrücke aus Zeichenketten isolieren will, um damit zu rechnen.
Für das Rechnen brauchen wir nämlich numerische Variablen, denn die üblichen Operatoren werden für Zeichenketten nicht funktionieren, weil sie hier andere Funktionen übernehmen (Man sagt auch, sie sind überladen).
Auch dazu ein Beispiel:
Code:
[COLOR=Navy][I][B]var[/B][/I][/COLOR] myString = [COLOR=DimGray]"3.141592654"[/COLOR]; [COLOR=Green] // Initialisieren von myString mit einer konstanten Zeichenkette, die den Wert von Pi repräsentiert [/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myDouble = parseFloat(myString); [COLOR=Green]// Initialisieren von myDouble mit dem in eine Gleitkomma Zahl gecasteten Zeichenkette[/COLOR] [COLOR=Green]// myDouble enthält nun eine Zahl mit der wir nun beliebig weiterrechnen können[/COLOR]
Solche expliziten Casts funktionieren aber nur, wenn es sich bei dem umzuwandelnden Ausdruck auch um etwas handelt, was sinnvoll Interpretiert werden kann.
So sollte es zum Beispiel nicht gemacht werden:
Code:
[COLOR=Navy][I][B]var[/B][/I][/COLOR] myString = [COLOR=DimGray]"Ich bin garantiert keine Zahl in Zeichenkettenform"[/COLOR];[COLOR=Green] // Initialisieren von myString mit einer konstanten Zeichenkette[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] myDouble = parseFloat(myString);[COLOR=Green] // Initialisieren von myDouble mit dem in eine Gleitkomma Zahl gecasteten Zeichenkette[/COLOR] [COLOR=Green]// Welchen Wert hat myDouble nun?[/COLOR] [Spoiler] [COLOR=Green]/* Die Antwort lautet: NaN NaN steht für "Not a Number" und signalisiert uns, dass aus offensichtlichen Gründen nicht korrekt gecastet werden konnte */[/COLOR] [/Spoiler]
Gültigkeit und Lebensdauer von Variablen
Womit wir mal wieder bei einem eventuell nicht ganz einfachen aber überaus wichtigen Thema sind.
Zentral geht es um die Frage, wo eine Variable gültig ist, also in welchem Bereich unseres Programmes sie definiert ist, sodass wir auch tatsächlich sie zugreifen können.
Nun, ich glaube man kann die Sache relativ kurz auf den Punkt bringen:
Eine Variable ist nach ihrer deklaration immer in dem Block, in dem sie deklariert wurde, sowie sämtlichen dazu untergeordneten Blöcken gültig.
Um das zu demonstrieren, bastle ich einfach mal ein paar Anweisungsblöcke zusammen und deklariere Variablen:
Code:
{ [COLOR=Green]// Anweisungsblock A[/COLOR]
[COLOR=Navy][I][B]var[/B][/I][/COLOR] a = [COLOR=Red]10[/COLOR];
{ [COLOR=Green]// Anweisungsblock B[/COLOR]
[COLOR=Navy][I][B]var[/B][/I][/COLOR] b = [COLOR=Red]20[/COLOR];
[COLOR=Green] // <-- Punkt 1[/COLOR]
{[COLOR=Green] // Anweisungsblock C[/COLOR]
[COLOR=Navy][I][B]var[/B][/I][/COLOR] c = [COLOR=Red]30[/COLOR];
}
{[COLOR=Green] // Anweisungsblock D[/COLOR]
[COLOR=Navy][I][B]var[/B][/I][/COLOR] d = [COLOR=Red]30[/COLOR];
{ [COLOR=Green]// Anweisungsblock E[/COLOR]
[COLOR=Navy][I][B]var[/B][/I][/COLOR] e = [COLOR=Red]40[/COLOR];
}
[COLOR=Green] // <- Punkt 2[/COLOR]
}
}
}
[COLOR=Green]// <-- Punkt 3[/COLOR]
[COLOR=Green]// Mal wieder eine kleine Denkaufgabe:
// Ich habe einige Punkte markiert; überlegt euch, welche Variablen bei jedem der Punkte definiert sind.[/COLOR]
[Spoiler]
[COLOR=Green]/*
Punkt 1: a, b
Punkt 2: a, b, d
Punkt 3: keine
*/[/COLOR]
[/Spoiler]
Der Überschrift zuliebe muss ich jetzt aber nochmal auf den Begriff Lebensdauer zu sprechen kommen.
Wobei sich das relativ schnell abhandeln lässt, weil JavaScript so etwas wie statische Variablen meines Wissens nicht unterstützt. Was praktisch nichts anderes bedeutet, als dass alle Variablen immer nur in dem Block existieren, in dem sie deklariert wurden.
Wurde dieser Block durchlaufen, ist die Variable und somit auch ihr Wert nicht mehr existent.
An dieser Stelle sollten wir auch nochmal auf die sogenannten globalen Variablen zu sprechen kommen.
Diese erkennt man immer daran, dass sie ausserhalb aller Funktionen deklariert werden, also in keinem Anweisungsblock stehen, sondern typischerweise ganz zu Anfang eines Scripts.
Globale Variablen existieren mit dem Einbinden des Scripts über die gesamte Programmlaufzeit und alle Funktionen des Scripts, in dem sie definiert sind, können auf sie zugreifen.
Bei D2NT sind das meistens Konstanten, also Variablen, die mit einem festen Wert initialisiert werden, welcher danach auch nicht mehr geändert wird.
Bezeichnung von Variablen
Zwar kann man die Bezeichner seiner Variablen frei wählen, solange nur gewisse Schlüsselbegriffe nicht darin vorkommen, trotzdem gibt es auch dabei eine gewisse Norm.
Bei D2NT sind folgende Dinge bei der Bezeichnung von Variablen typisch:
Code:
[COLOR=Green]// Insgesamt gilt, wenn auch nicht D2NT typisch: Jeder Teilbegriff innerhalb eines Bezeichners beginnt mit einem Großbuchstaben, um die Lesbarkeit zu erhöhen; z.B. myAwesomeValue[/COLOR] [COLOR=Green]// (Globale) Konstante [/COLOR][COLOR=Navy][I][B]const [/B][/I][/COLOR][COLOR=Green][COLOR=Black]MY_GLOBAL_CONST = [COLOR=Red]42[/COLOR];[/COLOR] // Die Bezeichner von Konstanten bestehen typischerweise nur aus Großbuchstaben // Globale Variable[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] MyGlobal = [COLOR=Red]2.5[/COLOR]; [COLOR=Green]// Die Bezeichner globaler Variablen beginnen typischerweise mit einem Großbuchstaben[/COLOR] [COLOR=Green]// Variable innerhalb einer Funktion[/COLOR] [COLOR=Navy][I][B]var[/B][/I][/COLOR] _myVar = [COLOR=Red]100[/COLOR]; [COLOR=Green]// Die Bezeichner von Variablen innerhalb von Funktionen beginnen mit einem Bodenstrich gefolgt von einem Kleinbuchstaben // Und als kleiner Ausblick: Formale Parameter von Funktionen; Beginnen mit Kleinbuchstaben z.B. myValue[/COLOR]
Case sensivity
Nun fange ich schon mit Plattdeutschen Überschriften an...
Aber auch dieser Punkt ist enorm wichtig: JavaScript ist in allen belangen case sensitive! Das bedeutet nichts anderes, als dass strikt zwischen Groß- und Kleinschreibung unterschieden wird.
Ihr müsst also bei den Bezeichnern eurer Variablen, wie auch bei sämtlichen Schlüsselbegriffen immer auf die richtige Schreibweise achten.
Schreibt ihr beispielsweise nur einen einzigen Buchstaben im Namen einer eurer zuvor deklarierten Variablen groß, obwohl der Buchstabe eigentlich klein sein sollte, dann sprecht ihr damit alles an, nur nicht eure Variable, auf die ihr eigentlich zugreifen wollt.
Bei den Schlüsselbegriffen sieht es genauso aus, ein falscher Buchstabe führt dazu, dass ein Begriff nicht bekannt ist und somit zu einem Syntaxfehler führt.
3. Arrays
Ein Array ist ein Datenfeld, sozusagen ein Verbund aus, der aus sehr vielen verschiedenen Variablen besteht.
Man könnte sich das bildlich als eine Art Kette von Variablen vorstellen, die natürlich aus vielen verschiedenen Kettengliedern besteht.
Jedes Kettenglied darin hat eine feste Nummer, welche man als Index bezeichnet und welche nullbasiert ist, was nichts anderes bedeutet, als dass das erste Element im Array den Index 0 hat (Unbedingt merken!).
Wie auch schon die normalen Variablen hat ein Array immer einen Bezeichner, wobei die einzelne Elemente mithilfe des Index angesprochen werden können. Der Index wird dazu in eckigen Klammern direkt hinter dem Bezeichner angegeben.
Auch hat jedes Array eine feste Größe, wobei diese dynamische anwachsen kann. Somit ist es kein Problem, mit fester größe erstellte Array nachträglich zu vergrößern, um weitere Daten einzufügen.
Anders als in anderen Programmiersprachen kann ein Array in JavaScript auch Variablen von unterschiedlichen Datentypen enthalten, für D2NT wird man dies aber vermutlich nicht brauchen.
Im übrigen sind Arrays in JavaScript Objekte, wir kommen später dazu, was das genau bedeutet, darum könnten hier einige Dinge etwas aus dem Himmel fallen, ich hoffe diese leuchten dann im späteren Verlauf ein.
Anlegen von Arrays
Hier gibt es verschiedene Möglichkeiten, ich stelle hier nur eine vor, welche aber auch recht häufig verwendet wird:
Code:
[COLOR=Green]// Deklaration eines Arrays der Größe 5 mithilfe des new Operators [/COLOR][B][COLOR=Navy][I]var[/I][/COLOR][/B][COLOR=Green][COLOR=Black] myArray = [/COLOR][/COLOR][COLOR=Navy][B][I]new[/I][/B][/COLOR][COLOR=Green][COLOR=Black] Array([COLOR=Red]5[/COLOR]);[/COLOR] // Nun haben wir zwar ein Array der Größe 5, aber alle 5 Felder haben noch keinen Wert // Darum weisen wir nun jedem Feld einen Wert zu, hier in Form von Zeichenketten; die einzelnen Felder sprechen wir dabei mit dem jeweiligen Feldindex über den [] Operator an:[/COLOR] myArray[[COLOR=Red]0[/COLOR]] = [COLOR=DimGray]"Das erste Array Element"[/COLOR]; myArray[[COLOR=Red]1[/COLOR]] = [COLOR=DimGray]"Das zweite Array Element"[/COLOR]; myArray[[COLOR=Red]2[/COLOR]] = [COLOR=DimGray]"Das dritte Array Element"[/COLOR]; myArray[[COLOR=Red]3[/COLOR]] = [COLOR=DimGray]"Das vierte Array Element"[/COLOR]; myArray[[COLOR=Red]4[/COLOR]] = [COLOR=DimGray]"Das fünfte Array Element"[/COLOR]; [COLOR=Green]// Das Array enthält nun all diese Zeichenketten und wir genau wie oben bei der Zuweisung mit Index und [] Operator auf den Inhalt der einzelnen Elemente zugreifen[/COLOR] [COLOR=Green]// Nun ist uns spontan eingefallen, dass wir noch ein Element mehr brauchen... [/COLOR] [COLOR=Green]// Kein Problem, wir können über die Elementfunktion bzw. Methode push() ganz einfach weitere Elemente hinten an das Array anhängen:[/COLOR] myArray.push([COLOR=DimGray]"Ein zuvor vergessener Datensatz"[/COLOR]); [COLOR=Green]// Das Array wurde nun um ein 6. Element erweitert, somit beträgt die Größe nun 6 und wir können wie gehabtmit Index und [] Operator auf den Inhalt dieses neuen Elements zugreifen // Anders als in anderen Programmiersprachen, kann man aber auch auf Elemente zugreifen und diese Initialisieren, deren Index die aktuelle Größe des Arrays übersteigt [/COLOR] [COLOR=Green]// Das Array wird dann automatisch bis zu diesem Index erweitert, wobei auch die Größe des Arrays auf den Wert des gewählten Index+1 mitwächst und alle dazwischenliegenden Elemente nicht initialisiert werden, das sieht dann so aus:[/COLOR] myArray[[COLOR=Red]8[/COLOR]] = [COLOR=DimGray]"Das neunte Array Element"[/COLOR]; [COLOR=Green]// Mit diesem Schritt wird die Größe des Arrays automatisch auf 9 erhöht, wobei nun das das 7. und 8. Element nicht definiert sind[/COLOR]
Bei D2NT werden Arrays meist in Schleifen durchlaufen, was den Quellcode sehr kompakt und elegant macht.
Zu Schleifen kommen wir später.
Da es bei D2NT doch öfter mal auftaucht, möchte ich auch noch erwähnen, dass Arrays kombiniert werden können, sodass mehrdimensionale Matrizen entstehen können.
Prinzipiell können dabei Strukturen mit Millionen von Dimensionen entstehen, obwohl in der Regel die Vorstellungskraft schon bei 3 Dimensionen aufhört. Ist aber nicht weiter schlimm, da das in der Praxis und bei D2NT bei 2 bis 3 Dimensionen bleibt.
Hier ein ganz kurzes Beispiel, nur damit ihr was damit anfangen könnt, wenn es euch mal über den Weg läuft:
Code:
[COLOR=Green]// Mal zur Abwechslung ein Beispiel, was sich die meisten vorstellen können: Wir speichern auf ein paar Positionen im D2 Inventar Zahlen: // Dazu müssen wir zunächst mal einen Ursprung definieren, damit es für jeden nachvollziehbar ist; dieser sei in der oberen linken Inventarecke, womit die oberste Zeile die erste Zeile und die linke Spalte die erste Spalte ist // Nun brauchen wir zunächst ein Array für die 4 Zeilen, in welche dann später je 10 Inventarfeld kommen: [/COLOR][B][COLOR=Navy][I]var[/I][/COLOR][/B][COLOR=Green][COLOR=Black] myInventory = [/COLOR][/COLOR][COLOR=Navy][B][I]new[/I][/B][/COLOR][COLOR=Green][COLOR=Black] Array([COLOR=Red]4[/COLOR]);[/COLOR] // Nun legen wir an jedem Index ein weiteres Array mit 10 Elementen für unsere Inventarfeld an:[/COLOR] myInventory[[COLOR=Red]0[/COLOR]] = [COLOR=Navy][B][I]new[/I][/B][/COLOR] Array([COLOR=Red]10[/COLOR]); [COLOR=Green]// Zeile 1 (obere Zeile)[/COLOR] myInventory[[COLOR=Red]1[/COLOR]] = [COLOR=Navy][B][I]new[/I][/B][/COLOR] Array([COLOR=Red]10[/COLOR]); [COLOR=Green]// Zeile 2[/COLOR] myInventory[[COLOR=Red]2[/COLOR]] = [COLOR=Navy][B][I]new[/I][/B][/COLOR] Array([COLOR=Red]10[/COLOR]); [COLOR=Green]// Zeile 3[/COLOR] myInventory[[COLOR=Red]3[/COLOR]] = [COLOR=Navy][B][I]new[/I][/B][/COLOR] Array([COLOR=Red]10[/COLOR]); [COLOR=Green]// Zeile 4 (untere Zeile)[/COLOR] [COLOR=Green]// Was wir nun geschaffen haben ist nichts anderes, als eine Matrix, die der Größe nach ein Inventar beschreiben kann // Typisch für eine Matrix, werden die einzelnen Felder nun durch Angabe von Zeilen- und Spaltenindex beschrieben; beide zusammen beschreiben ein ganz bestimmtes Inventarfeld // Ich initialisiere nun ein paar der Inventarfelder:[/COLOR] myInventory[[COLOR=Red]3[/COLOR]][[COLOR=Red]0[/COLOR]] = [COLOR=Red]42[/COLOR]; myInventory[[COLOR=Red]3[/COLOR]][[COLOR=Red]9[/COLOR]] = [COLOR=Red]12[/COLOR]; myInventory[[COLOR=Red]1[/COLOR]][[COLOR=Red]1[/COLOR]] = [COLOR=Red]9[/COLOR]; [COLOR=Green]// Mal eine Frage für alle die vorher aufgepasst haben: Welchen Wert hat myInventory[3][9] und myInventory[2][8]?[/COLOR] [SPOILER] [COLOR=Green]/* myInventory[3][9]: 12 <-- Dieses Feld haben wir selber initialisiert myInventory[2][8]: undefined <-- Dieses Feld wurde nicht von uns initialisiert, somit wurde auch noch kein Wert definiert */[/COLOR] [/SPOILER]
Code:
[B][COLOR=Navy][I]var[/I][/COLOR][/B] myArray = [COLOR=Navy][B][I]new[/I][/B][/COLOR] Array([COLOR=Red]5[/COLOR]);[COLOR=Green] // Deklarieren eines Arrays der Größe 5[/COLOR] [COLOR=Green]// Wir hängen hinten noch ein weiteres Element an[/COLOR] myArray.push([COLOR=DimGray]"Ein neues Element"[/COLOR]); [COLOR=Green]// Nun rufen wir die Größe des Arrays ab und speichern sie in einer weiteren Variable[/COLOR] [B][COLOR=Navy][I]var[/I][/COLOR][/B] myArraySize = myArray.length; [COLOR=Green]// Welchen Wert hat myArraySize nun?[/COLOR] [SPOILER] [COLOR=Green]/* Die Antwort lautet: 6 Durch das Anhängen des weiteren Elements ist die Größe von anfänglich 5 auf 6 gewachsen */[/COLOR] [/SPOILER]






