vorige Präsentation: Funktionen und Closures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation Stil + Tipps
Neben Funktionen und Klassen gibt es noch eine weitere Möglichkeit Javascript Code zu strukturieren: Module. Wozu braucht man sie? Dazu ein Blick zurück in die Geschichte von Javascript:
Häufig werden in einer Webseite Javascript-Programm aus verschiedenen Quellen kombiniert. Die Webseite enthält z.B.
Mit ein bisschen Copy-und-Paste kann man die verschiedenen Programme schnell in die eigene Webseite einbauen.
Aber achtung: all diese Programme laufen dann im selben Javascript Interpreter ab, und benutzen einen gemeinsamen globalen Namensraum.
Im “klassischen” Javascript kann Code mit dem script
Tag aus verschiedenen
Dateien geladen und zu einem Programm zusammen gesetzt werden.
Dabei gibt es nur einen Namensraum für den gesamten Code:
<h1>Diekt in der HTML Datei</h1>
<script>let a = 10;</script>
<script src="meinskript.js"></script>
<script>
console.log("kann b sehen", b);
b += 10;
console.log("kann b verändern", b);
</script>
let b = 2000;
console.log("kann a sehen", a);
a += 10;
console.log("kann a verändern", a);
Dieser gemeinsame Namensraum bringt viele Probleme: z.B. wenn ich ein fertiges Skript verwenden will, aber zufällig die gleichen Variablennamen oder Funktionsnamen selber schon verwendet habe.
Um Module im Browser zu verwenden, muss im script
Tag
das Attribut type
gesetzt sein:
<script type="module">
let a = 1;
</script>
Das Einbinden von externem Code erfolgt nun nicht mehr mit
dem script
Tag, sondern mit einem import
Statement:
<script type="module">
let a = 1;
import { b, setB } from './meinmodule.js';
</script>
Dabei wird genau angegeben, welche Variablen, Funktionen, Klassen ich aus der anderen Datei verwenden will.
Achtung: schon die HTML-Datei muss eine http oder https URL haben, ebenso die geladenen Javascript Dateien.
Mit einer file-URL erhält man eine Fehlermeldung:
Quellübergreifende (Cross-Origin) Anfrage blockiert: Die Gleiche-Quelle-Regel verbietet das Lesen der externen Ressource auf file:///…boardgame-counter/counter-7b.js. (Grund: CORS-Anfrage war nicht http). A Modul-Quell-URI ist in diesem Dokument nicht erlaubt: “file:///…index-7b.html”.
Nur die importierten Dinge sind dann zugänglich:
<script type="module">
let a = 1;
import { b, setB } from './meinmodule.js';
console.log(b); // Variable ist lesbar
// b += 10; // funktioniert nicht, importiert ist wie const
setB(42); // Funktion kann aufgerufen werden
</script>
Eine Zuweisung auf die Variable b
ist aber nicht möglich,
sie verhält sich hier wie eine const
.
In der importierten Datei sind vielleicht viele Variablen, Klassen,
Funktionen vorhanden. Aber nur diejenigen, die eine
einer export
Deklaration haben stehen für einen Import zur Verfügung:
export let b = 10;
let c = 'super secret';
Die Variable b
wird exportiert. Hier ist sie wirklich eine Variable, und kann
verändert werden.
Die Variable c
wird nicht exportiert, und kann
in der HTML-Datei oder in anderen Modulen nicht verwendet werden.
export let b = 10;
let c = 'super secret';
export function setB( newValue ) {
b = newValue;
}
Die Funktion setB
wird exportiert. Sie hat Zugriff auf die
Variable b
und kann sie verändern.
Man könnte die export-Deklarationen am Ende des Module zusammenfassen:
let b = 10;
let c = 'super secret';
function setB( newValue ) {
b = newValue;
}
export { b, setB };
Achtung: wenn wir Module verwenden gibt es kaum noch echte globale Variablen, die wir in den Developer Tools, in der Konsole direkt ausgeben können.
Statt dessen muss man auf den echten Debugger zurückgreifen, und einen Breakpoint setzen:
Mit diesem einfachen Mechanismus der Module kann man nun die Probleme des gemeinsamen Namensraumes vermeiden, und größere Programme in Teile zerlegen.
Da in einem Modul alle importe und export explizit angeführt sind, muss man (fast) nichts über das restliche Programm wissen, um ein einzelnes Module zu verstehen.
vorige Präsentation: Funktionen und Closures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation Stil + Tipps
/
#