Modernes JavaScript

Aus Zweites Gehirn, dem persönlichen Wiki
Modernes JavaScript
TypKonzept
QuellenQuelle - Angular Mastery Workshop
Erstellt2026-09-26
Aktualisiert2026-09-26
Tagsjavascript, programmiersprache, webentwicklung

Die Sprachmittel, die JavaScript seit ES2015 (ECMAScript 6) bekommen hat: let/const mit Blockgültigkeit, Pfeilfunktionen, ES-Module, nicht verändernde Array-Methoden, Spread und Destrukturierung sowie async/await. Sie bilden die Grundlage von TypeScript und Angular.

Alle Code-Beispiele stammen aus Quelle - Angular Mastery Workshop (Folie 28–66), von den Folienbildern abgeschrieben. Kommentare wie // Tony zeigen die Ausgabe laut Folie.

Variablen und Gültigkeitsbereich

const kann nicht neu zugewiesen werden, let schon. var ist der alte Stil (Folie 28):

// alter Stil
var hero = 'Superman'

// neuer Stil
let hero = 'Superman';    // kann neu zugewiesen werden
const hero = 'Superman';  // kann nicht neu zugewiesen werden

var gilt in der ganzen Funktion, let und const nur im Block { … } (Folie 29–35):

function foo(){
    if(true){
        var heroOne = 'Iron Man';     // Funktions-Scope
        const heroTwo = 'Superman';   // Block-Scope
        let heroThree = 'Batman';     // Block-Scope
    }
    console.log(heroOne);        // 'Iron man'
    console.log(heroTwo);        // heroTwo is not defined
    console.log(heroThree);      // heroThree is not defined
}

foo();

Quiz (Folie 36): Was gibt dieser Code aus?

function foo(){
    for(var i = 0; i < 5; i++) {
        setTimeout(function() {
            console.log(i);
        }, 0);
    }
}

foo();   // Logs 5, 5, 5, 5, 5

Lösung: var durch let ersetzen. Dann hat jeder Schleifendurchlauf sein eigenes i:

function foo(){
    for(let i = 0; i < 5; i++) {
        setTimeout(function() {
            console.log(i);
        }, 0);
    }
}

foo();   // Logs 0, 1, 2, 3, 4

Pfeilfunktionen

Aus einer klassischen Funktion wird eine Pfeilfunktion (Folie 37–38):

function getHero() { return 'Superman' }

const getHero = () => 'Superman'

Die Schreibweisen im Überblick (Folie 39–42):

// ein Parameter – Ausdruck
heroname => 'Iron man'

// mehrere Parameter – Ausdruck
(heroname, herologo) => `${heroname} ${herologo}`

// ein Parameter – Rückgabe nach Anweisungen
heroname => {
    // ... some logic
    return heroname;
}

// mehrere Parameter – Objekt zurückgeben (runde Klammern nötig!)
(heroname, herologo) => ({heroname, herologo})

this-Bindung (Folie 43–44): Eine klassische Funktion hat ihr eigenes this. Im setTimeout-Callback zeigt es deshalb nicht mehr auf das Objekt:

class HeroCaller {

    constructor(){
        this.heroName = 'Iron man';
    }

    callHero(){
        setTimeout(function(){            // ES5-Funktion
            console.log(`${this.heroName} arrived`);
        }, 2000);
    }
}

new HeroCaller().callHero();   // undefined arrived

Die Pfeilfunktion übernimmt this aus der Umgebung und funktioniert:

class HeroCaller {

    constructor(){
        this.heroName = 'Iron man';
    }

    callHero(){
        setTimeout(() => {                 // ES2015-Pfeilfunktion
            console.log(`${this.heroName} arrived`);
        }, 2000);
    }
}

ES-Module

Exportieren, dabei möglichst benannte Exporte statt default verwenden (Folie 45):

export const hero = 'Spiderman';

export function saveTheWorld(){};

export class Hero{};

export default class AnotherHero{};

Importieren (Folie 46–48):

import {hero, saveTheWorld, Hero} from './hero';  // benannte Exporte
import AnotherHero from './hero';                  // Default-Export
import * as heroStuff from './hero';               // vermeiden: alles aus ./hero landet im Bundle
import {hero as anotherhero} from './hero';        // Alias gegen Namenskonflikte

Vorteile: keine globalen Variablen, bessere Werkzeuge, weil sich Module statisch analysieren lassen, und Tree-Shaking, also das Entfernen von ungenutztem Code beim Bauen. Dazu das Zitat: „Good authors divide their books into chapters and sections; good programmers divide their programs into modules.“ (Folie 49)

Array-Methoden

filter und map erzeugen neue Arrays, statt das alte zu verändern (Folie 50–56):

const values = [1,2,3,4,5,6,7,8,9,10];

values.forEach(value => console.log(value));     // Logs 1,2,3,...,10

values.filter(value => value % 2 === 0);         // [2, 4, 6, 8, 10]

values.map(value => value * 5);                  // [5, 10, 15, ..., 50]

values.reduce((accumulated, value) => accumulated + value, 0);   // 55

values.includes(5);    // true
values.includes(11);   // false   (früher: .find(item => item === searchedItem))

Komplexeres reduce: zählen, wie oft jeder Eintrag vorkommt (Folie 54–55):

const calledHeroes = ['Iron Man', 'Iron Man', 'Batman', 'Spiderman'];

const missionInfos = calledHeroes.reduce((missionInfos, calledHero) => {
  !missionInfos[calledHero] ? missionInfos[calledHero] = 1 : missionInfos[calledHero]++;
  return missionInfos;
}, {});

console.log('Missioninfos', missionInfos);
// { 'Iron Man': 2, Batman: 1, Spiderman: 1 }

Spread und Destrukturierung bei Arrays

Spread übergibt ein Array als einzelne Argumente oder setzt Arrays zusammen, aber nur als flache Kopie (Folie 57):

const numbers = [1,2,3];

const sumThreeNumbers = (firstnumber, secondnumber, thirdnumber) =>
    firstnumber + secondnumber + thirdnumber;

console.log(sumThreeNumbers(...numbers));    // Logs: 6

const oneToFive = [1,2,3,4,5];
const fiveToTen = [6,7,8,9,10];

const numbers = [...oneToFive, ...fiveToTen];   // [1,2,3,4,5,6,7,8,9,10]

Destrukturierung, auch mit Auslassen und Standardwerten (Folie 58). Die Folie benutzt Emojis als Variablennamen, hier durch Wörter ersetzt:

const [ball, avocado, bear] = ['Football', 'Avocado', 'Bear'];
console.log(ball);      // Football   (früher: const ball = values[0];)

// 'Monkey' überspringen, Standardwert für fehlenden vierten Wert
const [ball, avocado, , bear, duck = 'Duck'] = ['Football', 'Avocado', 'Monkey', 'Bear'];
console.log(bear);      // Bear
console.log(duck);      // Duck
Fehler in der Quelle

Folie 58 behauptet: „Yes, emojis are valid variable names in Javascript 😉“. Das stimmt nicht: Die Emojis ⚽ 🥑 🐻 gehören nicht zu den Unicode-Zeichen, mit denen ein JavaScript-Bezeichner beginnen darf (ID_Start). Der Code auf der Folie ergibt einen Syntaxfehler. Umlaute oder griechische Buchstaben wären erlaubt (Einordnung Claude, nach der Sprachspezifikation).

Objekte

Object.keys, Object.values und Object.entries (Folie 59–60):

const heroes = {
  Ironman: {
    character: { firstname: 'Tony', name: 'Stark' },
    skills: 'genius level intellect, powered armor suit'
  },
  Superman: {
    character: { firstname: 'Clark', name: 'Kent' },
    skills: 'fly and superhuman strength'
  }
};

Object.keys(heroes);     // ['Ironman', 'Superman']
Object.values(heroes);   // [{character: {...}, skills: 'genius...'}, {character: {...}, skills: 'fly...'}]

// Schlüssel und Wert zusammen (oder Object.entries() verwenden)
Object.keys(heroes).forEach(key => {
    const hero = heroes[key];
    // ...
});

Kurzschreibweise, wenn Eigenschaft und Variable gleich heissen (Folie 61):

// ES5
const heroes = {
  ironman: ironman,
  superman: superman
}

// ES2015
const heroes = {
  ironman,
  superman
}

Objekt-Spread: ein ähnliches Objekt erzeugen und einzelne Eigenschaften überschreiben, wieder nur als flache Kopie (Folie 62):

const batman = {
    name: 'Batman',
    vehicle: 'batmobil',
    city: 'Gotham',
    country: 'USA'
}

const robin = {
    ...batman,
    name: 'Robin',
    vehicle: 'motorbike'
}

(Auf der Folie steht behicle statt vehicle. Mit dem Tippfehler würde robin beide Eigenschaften bekommen, statt vehicle zu überschreiben.)

Destrukturierung von Objekten, auch in Funktionsparametern, mit Umbenennung und Standardwert (Folie 63–65):

const ironMan = {
  firstname: 'Tony',
  lastname: 'Stark'
};

const {firstname, lastname} = ironMan;     // wie: const firstname = ironMan.firstname;
console.log(firstname);    // Tony

// in Funktionsparametern (die Klammern um {…} sind Pflicht)
const logName = ({firstname, lastname}) => console.log(`${firstname} ${lastname}`);
logName(ironMan);          // Tony Stark

// umbenennen und Standardwert
const {firstname, lastname: name, heroname = 'IronMan'} = ironMan;
console.log(name);         // Stark
console.log(heroname);     // IronMan

async / await

Eine async-Funktion gibt immer ein Promise zurück, await wartet auf ein Promise (Folie 66, TypeScript-Schreibweise):

const someFunction = async (): Promise<boolean> => {
  return await service.getValue();   // Folie: getVale (Tippfehler)
}

Der Kurs warnt, dass Zone.js natives async/await nicht abfangen kann.

Einordnung (Claude)

Diese Warnung hat sich weitgehend erledigt: Seit Angular 21 laufen neue Projekte ohne Zone.js (Quelle - Recherche - Angular heute 2026, siehe Angular-Komponente).

Diese Arbeitsweise ohne Veränderung der Originaldaten (Immutability) ist auch in Angular wichtig: Mit OnPush erkennt Angular Änderungen nur an einer neuen Referenz (siehe State Management).

Verwandt