diff --git a/src/components/slides/javascript/00-intro/index.astro b/src/components/slides/javascript/00-intro/index.astro new file mode 100644 index 0000000..b094203 --- /dev/null +++ b/src/components/slides/javascript/00-intro/index.astro @@ -0,0 +1,38 @@ +--- +import Title from "./title.astro"; +import Meta from './meta.astro'; +import ProjectSetup from './project-setup.astro'; +import Output from './output.astro'; +import Variables from "./variables.astro"; +import PrimitiveDatatypes from "./primitive-datatypes.astro"; +--- + +
+ + \ No newline at end of file diff --git a/src/components/slides/javascript/00-intro/meta.astro b/src/components/slides/javascript/00-intro/meta.astro new file mode 100644 index 0000000..acf6783 --- /dev/null +++ b/src/components/slides/javascript/00-intro/meta.astro @@ -0,0 +1,85 @@ +JavaScript ist eine Programmiersprache mit der Inhalte auf einer Website manipuliert werden können (Read, Create, Update, Delete).
+Ihr Haupteinsatszweck befindet sich in Browsern, aber JavaScript und sein "Ökosystem" sind so groß gewachsen, dass es nahezu überall verwendet werden kann.
+JavaScript ist eine Script-Sprache.
+Code wird nicht kompiliert sondern wird mit einem Interpreter "geparsed" und dynamisch ausgeführt.
+JavaScript hat - obwohl sein Name - NICHTS mit Java zu tun.
+JavaScript als Sprache wird von einem Standard beschrieben: ECMAScript.
+In Summe sind JavaScript und ECMAScript ein Synonym zueinander und sind entsprechend gleich (falls Ihnen einmal "ECMAScript" vorkommen sollte)
+Features von JavaScript
+Alles in allem ist JavaScript (JS) eine mächtige Sprache.
+Dadurch lassen sich viele Dinge "implementieren", die in anderen Sprachen nur durch Mehraufwand möglich sind.
+Problem hierbei ist aber auch, dass unerfahrene Entwickler öfters gravierende Fehler produzieren können, die JS "verschluckt" und dies wiederum zu ungewollten Situation in der Website führt.
+Die Sprache selber hat nur ein paar Kernfunktionalitäten. Browser und andere Runtimes ermöglichen den Zugriff auf verschiedene API's.
+So bieten Browser eine DOM-API an, um auf das Dokument selbst zuzugreifen, während NodeJS (eine Runtime zum ausführen auf dem Computer) API's zum Zugriff auf das Dateisystem bereitstellen.
+Funktionen sind einfach als Variablen definiert. Man kann sie ggf. überschreiben und an andere Funktionen übergeben.
+In JavaScript ist alles ein Objekt mit dem man Interagieren kann.
+Je nachdem des Typen des Objektes (zum Beispiel "String"), enthält dieser Objekt-Typ Grundlegende Funktionalitäten, die als "Prototypen" definiert sind.
+Im Grundlegensten Sinne kann man das als Klassenbasiertes Verhalten Kennzeichnen.
+JavaScript ist eine sehr Flexible Sprache. Sie lässt verschiedene Programmier-Arten zu die auch alle untereinander verwendet werden können.
+Beispiele sind: Objektorientert (mittels Klassen), Funktional (moderne Frameworks sind meist so aufgebaut), etc.
+Als Programmierer entwickelt man auf einem einzigen Thread. Hat für uns Entwickler den Vorteil das wir nicht auf Concurrency achten müssen.
+Nachteil hierbei ist natürlich: Wenn der Thread einen Deadlock o.ä. hat, können wir uns davon nicht mehr erholen.
+Aber JS bietet moderne Lösungen um lang anhaltende Operationen "auszulagern". Mehr dazu später.
+In JS müssen Datentypen nicht explizit deklariert werden. Tatsächlich lassen sich keine Datentypen auf Variablen deklarieren.
+Moderne SuperSets wie TypeScript bilden eine Schicht auf JavaScript, um ein komplexes Typensystem zu implementieren. Am Ende wird aber jeglicher Code für Browser verständlich gebaut.
+Um später unsere Berechnungen zu testen, müssen wir natürlich erstmal wissen, welche Möglichkeiten wir haben um Daten aus JS heraus anzuzeigen.
+Diese Art der Ausgabe wird der (reguläre) Nutzer nicht sehen. Sie ist in den Entwickler-Tools des Browsers zu sehen.
+Neben console.log()
gibt es noch weitere Ausgabemöglichkeiten wie .warn()
, .info()
oder error()
.
Diese Art der Ausgabe hilft uns als Entwickler potenzielle Fehler zu identifizieren, während wir unsere Website entwickeln.
+Schreiben wir nun unser erstes JavaScript!
+
+ console.log("Hier könnte Ihre Werbung stehen!");
+
+ In den Entwickler-Tools unter dem Reiter "Console" (Sprachenabhängig), sollte nun der ausgegebene Text zu sehen sein.
+Innerhalb des Web-Browsers haben wir ein Objekt zur Verfügung mit dem wir auf das HTML-Dokument zugreifen können.
+Wir werden später mehr darüber erfahren, aber fürs erste nutzen wir die erste von vielen Funktionen: document.writeln()
.
Dieses Kommando schreibt den Inhalt den wir der Funktion Übergeben in das Dokument.
+Lasst uns etwas ins Dokument schreiben!
+
+ document.writeln("Hallo Welt!");
+
+ Natürlich kann der Text auch in HTML geschrieben sein:
+
+ document.writeln("<p><code>Monospace it is!</code></p>");
+
+ Schauen wir uns mal näher an, was wir da genau in den Variablen bisher gespeichert haben.
+Hierfür haben wir ein kleines Keyword in JS, dass uns hilft den Datentypen zu identifizieren.
+Wir nutzen das keyword typeof
um den Datentypen einer Variable auszugeben.
+ const message = "Hallo Welt!";
+
+ // Gibt "string" aus
+ document.writeln(typeof message);
+
+ Nun, wir wussten bereits vorher, dasss wir einen String verwendet haben. Der Text war in doppelten Anführungszeichen.
+Strings beinhalten Texte. Die Länge des Textes muss nicht angegeben werden wie in alten Programmiersprachen (z.B. C).
+Das Konzept des Grundlegenden Datentypes "char" gibt es in JS nicht. Alles ist ein String.
+Entsprechend ist es egal, ob man doppelte oder einfache Anführungszeichen verwendet.
+
+ let message = 'Geht auch einfach!';
+
+ document.writeln(message);
+
+ Es gibt eine dritte Art, Strings zu definieren, und zwar in sogenannten "Backticks" (``).
+Wenn wir diese Backticks verwenden, erzeugen wir in JavaScript ein sogenanntes "Template Literal", mit dem wir ganz einfach Variablen innerhalb des Strings verwenden können.
+Um Variablen im String zu referenzieren, müssen diese nur in geschweiften Klammer mit einem anführenden Dollar-Zeichen geschrieben sein
+
+ const world = "Welt";
+ const message = `Hello, ${world}!`;
+
+ // Gibt "Hallo, Welt!" aus
+ document.writeln(message);
+
+ Strings besitzen eine Reihe an eingebauten Funktionen, um diese zu modifizeren, Tests auszuführen oder aufzuteilen.
+Wir können Strings in JS wie ein Array "behandeln" und mit eckigen Klammern auf einen bestimmten Index innerhalb des Strings zugreifen.
+ +
+ let hello = "Hallo";
+
+ // Gibt 'a' aus
+ document.writeln(hello[1]);
+
+ Mittels concat
, können wir einen String, mit einem oder mehreren anderen zusammenführen.
+ const hello = "Hallo";
+ const world = "Welt!";
+ const message = hello.concat(', ', world);
+
+ // Gibt "Hallo, Welt!" aus
+ document.writeln(message);
+
+ Mit includes
können wir abfragen, ob in einem String ein bestimmtes Wort / Wörter enthalten sind.
+ const message = "Hallo Welt!";
+
+ document.writeln(message.includes("Welt!"));
+ document.writeln(message.includes("Welt?"));
+
+ Wollen wir den Inhalt eines Strings mit etwas neuem austauschen, so nutzen wir replace
oder replaceAll
Die Operation modifiziert den existierenden String nicht. Sie gibt einen neuen String aus der modifiziert wurde
+ +
+ const message = "Hallo, Welt!";
+
+ // Gibt "Hallo, Stundenten!" aus;
+ document.writeln(message.replace("Welt", "Studenten"));
+ // Gibt "HaLLo, WeLt!" aus
+ document.writeln(message.replaceAll('l', 'L'));
+
+ replace
tauscht nur das erste "Vorkommen" in einem String aus.
Während replaceAll
alle Vorkommen austauscht. Interessanterweise gibt es replaceAll erst seit kurzer Zeit.
Wir können einen String in ein Array aufsplitten indem wir ein bestimmtes Zeichen, beziehungsweise eine Zeichenfolge als "trenner" bestimmen
+
+ const message = "Hallo, Welt!";
+ // Gibt "Ha,,o, We,t!" aus
+ document.writeln(message.split('l'));
+
+ Wichtig hierbei ist zu wissen, das document.writeln
, ein Array aus Strings annimmt und die Werte Komma-separiert ausgibt.
Anstatt es ins Dokument zu schreiben, geben Sie message.split('l')
nun einmal in der Konsole aus.
Mit den Funktionen toLowerCase
und toUpperCase
können wir alle Buchstaben in GROßE und kleine Umwandeln.
+ const message = "Hallo, Welt!";
+
+ console.log(message.toUpperCase());
+
+ Auch hier wird der originale String nicht modifiziert, sondern eine modifizierte Version zurück gegeben.
+In JS können natürlich Zahlen in Variablen stecken.
+Aufgrund der fehlenden Unterscheidung der Datentypen, beinhaltet der Datentyp "number" sowohl ganze Zahlen aus auch Long Floating Point Zahlen (Double Precision)
+Rechenoperationen sind genauso möglich wie in allen anderen Sprachen
+
+ const theAnswer = 40 + (2*2) - (20/10);
+
+ document.writeln(`Die Antwort auf alles lautet ${theAnswer}`);
+
+ Mittels den Funktionen parseInt
und parseFloat
kann eine Zahl aus einem String konvertiert werden.
+ const parsedInt = parseInt("314");
+ document.writeln(`{parsedInt}`);
+
+ Die Funktion scannt eine Zahl so lange, bis sie ein "invalides" Zeichen findet und liefert dann das gefundene Resultat (oder "NaN")
+Not a Number
+Falls JS den String nicht konvertieren kann, ist der Zahlenwert "Not a Number".
+Mit der Funktion "isNaN" kann geprüft werden ob eine Konversion erfolgreich war.
+Wenn wir eine lange Kommazahl verkürzt darstellen wollen, gibt es noch die Funktion toFixed
+ const longFloat = 3.14159265358979323;
+ document.writeln(`Die ersten 5 Nachkommestellen von PI sind: longFloat.toFixed(2)`)
+
+ Wie in anderen Sprachen kann ein Bool in JS 2 Werte annehmen: true
und false
+ const wahr = true;
+ const falsch = false;
+
+ Wir werden in den nächsten Folien über Control-Flows reden, bis dahin reicht uns zu wissen das wir einfache wahr/falsch Zustände haben können.
+JavaScript kennt 2 Arten um "nichts" darzustellen: undefined
und null
.
Wenn eine Variable deklariert aber nicht initialisiert wird, ist sie zu Beginn undefined
.
Wir können uns also undefined als einen impliziten Zustand vorstellen, wenn etwas (noch) nicht definiert ist.
+
+ let message;
+
+ document.writeln(`Ich bin ${undefined}`);
+
+ null
stellt eine intentionelle Zuweisung eines nicht existierenden Wertes dar.
Nichtsdestotrotz ist es möglich, eine Variable mit dem Wert undefined
explizit zu initialisieren.
Wir können noch bei einfachen Anwendungen weiterhin unser "altbewährtes" Setup weiter verwenden.
+Trotzdem möchte ich an diesem Punkt "erweiterte" Setups abdecken die uns später eindeutig mehr helfen werden.
+Wenn wir das alte Setup noch weiter verwenden wollen, müssen wir nur eine JavaScript-Datei anlegen (Dateiendung .js).
+Im HTML kann das Script dann mittels dem Script-Tag eingebunden werden:
+
+ // Das Script-Tag kann nicht mit einem <script/>
+ // abgekürzt werden.
+ // Es braucht zwingend ein Start und End-Tag
+
+
+ Man könnte nun auch JS innerhalb des script-tags schreiben, bei wachsenden Projekten leidet hier aber die Übersichtlichkeit
+Nun können wir in der Datei "mein-script.js" Anfangen JS zu schreiben.
+Für diesen Teil muss NodeJS als Programm auf dem Laptop installiert sein.
+Mit NodeJS mitenthalten ist der Package-Manager "npm" (node package manager). Mit diesem werden wir das Build-Tool "Vite" verwenden.
+Vite bietet uns ein Boilerplate-Projekt an von dem wir schnell starten können
+
+ npm create vite@latest js-intro -- --template vanilla
+ cd js-intro
+ npm install
+ npm run dev
+
+ npm create vite@latest js-intro -- --template vanilla
+ Wir nutzen npm um damit ein Projekt mit vite (in der aktuellesten Version) zu erstellen.
+Das Projekt soll in den Ordner "js-intro" platziert werden.
+Das Doppel-Minus dient als Trenner um Parameter an das Kommando "vite@latest" zu senden.
+Hier teilen wir Vite mit, dass es das Vanilla-Template verwenden soll.
+In der JS Welt gibt es mittlerweile sehr viele Möglichkeiten sein Frontend zu bauen. Diese Frameworks und Bibliotheken nehmen einem in großen Projekten sehr viel Arbeit ab und helfen dem Entwickler sich auf die eigentliche Implementierung der Website zu konzentrieren.
+Projekte die diese Möglichkeiten nicht nutzen werden in der Entwickler-Community als Vanilla-Projekte bezeichnet.
+Innerhalb des neu erstellen Projektes kann man die Datei "counter.js" löschen, und den Inhalt innerhalb von "main.js" entfernen.
+Die CSS-Datei können wir optional so behalten oder auch leeren (wenn wir wirklich von 0 an Anfangen wollen).
+Wenn wir Vite verwenden haben wir ein tolles Feature, dass uns bei der Entwicklung "etwas" unter die Hände greift: Hot-Module-Replacement (oder auch kurz HMR).
+Sobald wir eine Datei ändern und speichern, werden die Änderungen auf der Website sofort ersichtlich.
+Mit diesem Setup werden wir für längere Zeit weiter arbeiten.
+
+ dhbw/
+ ├── 00-introduction/
+ │ └── index.html
+ └── index.html
+ node_modules/
+ └── ...
+ public/
+ └── ...
+ src/
+ └── ...
+ .gitignore
+ index.html
+ package-lock.json
+ package.json
+
+ Schauen wir uns nun an, wie wir in JS Variablen anlegen können.
+Grundlegend gibt es 2 "Arten" von Variablen: Konstanten und änderbare Variablen
+In JS müssen wir nicht angeben, was für ein Typ eine Variable hat. Anhand des aktuellen Wertes weiß JS womit wir arbeiten und kennt somit auch die Möglichkeiten, was wir mit der Variable "anstellen" können.
+Mit const
lassen sich Konstante Variablen definieren.
Die Variable nach dem Anlegen nicht mehr ändern, so wie man es auch aus anderen Programmiersprachen kennt.
+
+ const message = "Ziemlich konstant hier";
+ document.writeln(message);
+
+ message = "Oder vielleicht doch nicht?";
+ document.writeln(message);
+
+ Wir sollten nun mehrere Sachen beobachten können:
+Es sollte eine Nachricht in der Konsolenausgabe der Entwickler-Tools erscheinen. In dieser steht wir können nichts mehr zur Variable "message" zuweisen.
+Aber es gibt noch eine wichtige Sache: Wir haben die Nachricht "Ziemlich konstant hier" einmal im Dokument stehen. Die 2. Ausgabe erscheint hier nicht mehr.
+JavaScript beendet die Abarbeitung von Code, sobald ein Fehler auftritt.
+Dies bedeutet nicht, dass man gar kein JS mehr ausführen kann. Nur die Ausführung im aktuellen Call-Stack wurde beendet.
+Hier haben Skript-Sprachen einen gravierenden Unterschied gegenüber kompilierten Sprachen:
+Eine Skript-Sprache führt den Code, der "eingescannt" wurde, (in der Regel) sofort aus. Dem Gegenüber stehen kompilierte Sprachen, die einen Haupteinstiegspunkt haben (Java: public static void main(...)
)
In dem Moment, in dem der gesamte Code aus der JS-Datei vom Browser eingescannt wurde, hat der Browser auch angefangen den Code auszuführen.
+Der Code in Zeile 5 wird niemals ausgeführt
+
+ const message = "Ziemlich konstant hier";
+ document.writeln(message);
+
+ message = "Oder vielleicht doch nicht?";
+ document.writeln(message);
+
+ Das Gegenteil zum Konstanten bildet hier let
ab.
Eine Variable mit let
initialisiert kann jederzeit neu beschrieben werden (zum Verlust der alten Daten natürlich).
+ let message = "Das ist nur der Anfang!";
+ document.writeln(message);
+
+ message = "Aber wann kommt das Ende?";
+ document.writeln(message);
+
+ Bevor es let
gab, existierte var
.
Beide haben "leicht" andere Verhaltensweisen, die wir sehen werden, sobald wir uns das Thema "Scoping" näher betrachten.
+Insgesamt ist aber meine Empfehlung, let
zu verwenden. Das Verhalten ist kontrollierter gegenüber var