Fortgeschritten302025-01-15

JavaScript ES6+ Features - Moderne JavaScript Syntax

Lerne die wichtigsten ES6+ Features: Destructuring, Spread/Rest, Arrow Functions, Template Literals, Optional Chaining und mehr.

#javascript#es6#destructuring#spread#arrow-functions#modern-js

JavaScript ES6+ Features

ES6 (ECMAScript 2015) und die neueren Versionen haben JavaScript revolutioniert! Diese Features machen deinen Code kürzer, lesbarer und moderner.

1. Arrow Functions - Kürzere Funktionen

Arrow Functions (=>) sind eine kürzere Syntax für Funktionen.

Arrow Functions vs. Normal Functions
// ❌ Old School
function add(a, b) {
  return a + b;
}

// ✅ ES6 Arrow Function
const add = (a, b) => {
  return a + b;
};

// ✅✅ Noch kürzer (implicit return)
const add = (a, b) => a + b;

console.log(add(5, 3)); // 8

Arrow Functions - Verschiedene Syntax-Varianten

Arrow Function Syntax
// Keine Parameter
const greet = () => 'Hello!';
console.log(greet()); // 'Hello!'

// Ein Parameter (Klammern optional)
const double = num => num * 2;
console.log(double(5)); // 10

// Mehrere Parameter (Klammern erforderlich)
const add = (a, b) => a + b;
console.log(add(3, 4)); // 7

// Mehrzeilig mit return
const calculate = (a, b) => {
  const sum = a + b;
  const product = a * b;
  return { sum, product };
};

// Objekt zurückgeben (in Klammern!)
const createUser = (name, age) => ({ name, age });
console.log(createUser('Anna', 25));
// { name: 'Anna', age: 25 }

Arrow Functions - this Binding

Arrow Functions haben kein eigenes this!

this in Arrow Functions
const person = {
  name: 'Anna',

  // ❌ Normale Funktion - eigenes this
  greet: function() {
    setTimeout(function() {
      console.log('Hi, ich bin ' + this.name);
      // this.name ist undefined!
    }, 1000);
  },

  // ✅ Arrow Function - erbt this
  greetArrow: function() {
    setTimeout(() => {
      console.log(`Hi, ich bin ${this.name}`);
      // this.name funktioniert! ✅
    }, 1000);
  }
};

person.greet(); // 'Hi, ich bin undefined'
person.greetArrow(); // 'Hi, ich bin Anna'

2. Template Literals - String-Interpolation

Template Literals verwenden Backticks (``) statt Anführungszeichen.

Template Literals Basics
const name = 'Anna';
const age = 25;

// ❌ Old School - String Concatenation
const message = 'Hallo, ich bin ' + name + ' und ' + age + ' Jahre alt.';

// ✅ ES6 Template Literal
const message = `Hallo, ich bin ${name} und ${age} Jahre alt.`;

console.log(message);
// 'Hallo, ich bin Anna und 25 Jahre alt.'

// Berechnungen in ${}
const price = 19.99;
const quantity = 3;
console.log(`Gesamt: ${price * quantity}€`);
// 'Gesamt: 59.97€'

Mehrzeilige Strings

Multiline Strings
// ❌ Old School
const html = '<div>\n' +
             '  <h1>Titel</h1>\n' +
             '  <p>Text</p>\n' +
             '</div>';

// ✅ ES6 Template Literal
const html = `
<div>
  <h1>Titel</h1>
  <p>Text</p>
</div>
`;

console.log(html);

3. Destructuring - Werte extrahieren

Destructuring erlaubt es, Werte aus Arrays und Objekten zu extrahieren.

Array Destructuring

Array Destructuring
const colors = ['red', 'green', 'blue'];

// ❌ Old School
const first = colors[0];
const second = colors[1];

// ✅ ES6 Destructuring
const [first, second, third] = colors;

console.log(first);  // 'red'
console.log(second); // 'green'
console.log(third);  // 'blue'

// Elemente überspringen
const [red, , blue] = colors;
console.log(red, blue); // 'red' 'blue'

// Rest operator
const [firstColor, ...rest] = colors;
console.log(firstColor); // 'red'
console.log(rest);       // ['green', 'blue']

// Default values
const [a, b, c, d = 'yellow'] = colors;
console.log(d); // 'yellow'

Object Destructuring

Object Destructuring
const user = {
  name: 'Anna',
  age: 25,
  city: 'Berlin',
  country: 'Germany'
};

// ❌ Old School
const name = user.name;
const age = user.age;

// ✅ ES6 Destructuring
const { name, age, city } = user;

console.log(name); // 'Anna'
console.log(age);  // 25
console.log(city); // 'Berlin'

// Umbenennen
const { name: userName, age: userAge } = user;
console.log(userName); // 'Anna'

// Default values
const { name, age, job = 'Developer' } = user;
console.log(job); // 'Developer'

// Rest operator
const { name, ...details } = user;
console.log(details);
// { age: 25, city: 'Berlin', country: 'Germany' }

Nested Destructuring

Verschachteltes Destructuring
const user = {
  name: 'Anna',
  address: {
    city: 'Berlin',
    zip: '10115',
    country: 'Germany'
  }
};

// Verschachtelt destructuren
const {
  name,
  address: { city, country }
} = user;

console.log(name);    // 'Anna'
console.log(city);    // 'Berlin'
console.log(country); // 'Germany'

Destructuring in Funktionen

Function Parameter Destructuring
// ❌ Old School
function greet(user) {
  console.log(`Hallo ${user.name}, du bist ${user.age} Jahre alt`);
}

// ✅ ES6 Destructuring
function greet({ name, age }) {
  console.log(`Hallo ${name}, du bist ${age} Jahre alt`);
}

greet({ name: 'Anna', age: 25 });
// 'Hallo Anna, du bist 25 Jahre alt'

// Mit Default Values
function createUser({ name, age = 18, role = 'user' }) {
  return { name, age, role };
}

console.log(createUser({ name: 'Max' }));
// { name: 'Max', age: 18, role: 'user' }

4. Spread Operator - Elemente verteilen

Der Spread Operator (...) "verteilt" Elemente aus Arrays oder Objekten.

Array Spread

Spread mit Arrays
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// ❌ Old School - concat()
const combined = arr1.concat(arr2);

// ✅ ES6 Spread
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]

// Element hinzufügen
const withExtra = [...arr1, 999, ...arr2];
console.log(withExtra); // [1, 2, 3, 999, 4, 5, 6]

// Array kopieren
const copy = [...arr1];
console.log(copy); // [1, 2, 3]

Object Spread

Spread mit Objekten
const user = {
  name: 'Anna',
  age: 25
};

const address = {
  city: 'Berlin',
  country: 'Germany'
};

// ✅ Objekte kombinieren
const userWithAddress = {
  ...user,
  ...address
};

console.log(userWithAddress);
// {
//   name: 'Anna',
//   age: 25,
//   city: 'Berlin',
//   country: 'Germany'
// }

// Properties überschreiben
const updatedUser = {
  ...user,
  age: 26,          // Überschreibt age
  job: 'Developer'  // Neues Property
};

console.log(updatedUser);
// { name: 'Anna', age: 26, job: 'Developer' }

// Objekt kopieren
const userCopy = { ...user };

Spread in Funktionen

Spread als Function Arguments
const numbers = [5, 10, 3, 8, 1];

// ❌ Old School
const max = Math.max.apply(null, numbers);

// ✅ ES6 Spread
const max = Math.max(...numbers);
console.log(max); // 10

// Function mit vielen Parametern
function sum(a, b, c, d) {
  return a + b + c + d;
}

const nums = [1, 2, 3, 4];
console.log(sum(...nums)); // 10

5. Rest Parameter - Sammle Argumente

Der Rest Parameter (...) sammelt mehrere Argumente in ein Array.

Rest Parameter
// ✅ Rest Parameter - beliebig viele Argumente
function sum(...numbers) {
  return numbers.reduce((acc, num) => acc + num, 0);
}

console.log(sum(1, 2, 3));       // 6
console.log(sum(1, 2, 3, 4, 5)); // 15

// Rest mit anderen Parametern kombinieren
function greet(greeting, ...names) {
  return `${greeting} ${names.join(', ')}!`;
}

console.log(greet('Hallo', 'Anna', 'Max', 'Lisa'));
// 'Hallo Anna, Max, Lisa!'

// Rest muss IMMER am Ende stehen!
// function wrong(...rest, last) {} ❌ Fehler!

6. Default Parameters - Standardwerte

Funktionen können Standardwerte für Parameter haben.

Default Parameters
// ❌ Old School
function greet(name) {
  name = name || 'Gast';
  return 'Hallo ' + name;
}

// ✅ ES6 Default Parameter
function greet(name = 'Gast') {
  return `Hallo ${name}`;
}

console.log(greet('Anna')); // 'Hallo Anna'
console.log(greet());       // 'Hallo Gast'

// Mit Berechnungen
function createArray(length = 10, fill = 0) {
  return Array(length).fill(fill);
}

console.log(createArray(5, 1));  // [1, 1, 1, 1, 1]
console.log(createArray());      // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

7. Enhanced Object Literals

ES6 macht die Objekt-Erstellung einfacher!

Enhanced Object Literals
const name = 'Anna';
const age = 25;

// ❌ Old School
const user = {
  name: name,
  age: age,
  greet: function() {
    return 'Hallo!';
  }
};

// ✅ ES6 - Property Shorthand
const user = {
  name,  // Gleich wie name: name
  age,   // Gleich wie age: age

  // Method Shorthand
  greet() {
    return 'Hallo!';
  }
};

// Computed Property Names
const key = 'favoriteColor';
const user = {
  name: 'Anna',
  [key]: 'blue',  // Property name dynamisch
  [`is${name}`]: true  // Berechnet
};

console.log(user);
// {
//   name: 'Anna',
//   favoriteColor: 'blue',
//   isAnna: true
// }

8. Optional Chaining (?.)

Optional Chaining verhindert Fehler bei undefined oder null.

Optional Chaining
const user = {
  name: 'Anna',
  address: {
    city: 'Berlin'
    // zip fehlt!
  }
};

// ❌ Old School - Kann crashen!
const zip = user.address.zip.toUpperCase();
// TypeError: Cannot read property 'toUpperCase' of undefined

// ❌ Old School - Sicher aber umständlich
const zip = user && user.address && user.address.zip
  ? user.address.zip.toUpperCase()
  : 'N/A';

// ✅ ES2020 Optional Chaining
const zip = user.address?.zip?.toUpperCase();
console.log(zip); // undefined (kein Fehler!)

// Mit Default Value
const zip = user.address?.zip?.toUpperCase() ?? 'N/A';
console.log(zip); // 'N/A'

Optional Chaining mit Funktionen

Optional Chaining mit Methods
const user = {
  name: 'Anna',
  greet() {
    return 'Hallo!';
  }
};

// Methode existiert
console.log(user.greet?.()); // 'Hallo!'

// Methode existiert NICHT
console.log(user.goodbye?.()); // undefined (kein Error!)

// Optional Chaining mit Arrays
const users = [
  { name: 'Anna' },
  { name: 'Max' }
];

console.log(users[0]?.name);  // 'Anna'
console.log(users[5]?.name);  // undefined
console.log(users[5]?.greet?.()); // undefined

9. Nullish Coalescing (??)

Der Nullish Coalescing Operator (??) gibt den rechten Wert zurück, wenn der linke null oder undefined ist.

Nullish Coalescing vs. OR
// Problem mit || operator
const count = 0;
const result1 = count || 10;
console.log(result1); // 10 (aber 0 ist valide!)

const name = '';
const result2 = name || 'Gast';
console.log(result2); // 'Gast' (aber '' ist valide!)

// ✅ Nullish Coalescing - nur bei null/undefined
const count = 0;
const result1 = count ?? 10;
console.log(result1); // 0 ✅

const name = '';
const result2 = name ?? 'Gast';
console.log(result2); // '' ✅

// Nur bei null/undefined wird Default verwendet
const value = null;
const result3 = value ?? 'Default';
console.log(result3); // 'Default'

10. let & const - Block Scope

let und const haben Block Scope (nicht Function Scope wie var).

let vs const vs var
// var - Function Scope (alt)
if (true) {
  var x = 10;
}
console.log(x); // 10 (var ist außerhalb sichtbar!)

// let - Block Scope
if (true) {
  let y = 20;
}
// console.log(y); // ReferenceError!

// const - Block Scope + nicht neu zuweisbar
const PI = 3.14;
// PI = 3.14159; // TypeError!

// const mit Objekten
const user = { name: 'Anna' };
user.name = 'Max'; // ✅ Properties ändern geht!
// user = { name: 'Max' }; // ❌ Neu zuweisen geht NICHT!

Wann was verwenden?

let vs const - Best Practices
// ✅ const als Standard (wird nicht neu zugewiesen)
const userName = 'Anna';
const userAge = 25;

// ✅ let wenn Wert sich ändert
let counter = 0;
counter++;
counter++;

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

// ❌ var vermeiden (veraltet)
var oldStyle = 'bad';

11. Modules - Import/Export

ES6 Modules erlauben es, Code in separate Dateien zu organisieren.

Export - utils.js
// Named Exports
export const PI = 3.14;

export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

// Default Export (nur einer pro Datei)
export default function multiply(a, b) {
  return a * b;
}
Import - main.js
// Named Imports (mit {})
import { add, subtract, PI } from './utils.js';

console.log(add(5, 3));      // 8
console.log(subtract(10, 4)); // 6
console.log(PI);             // 3.14

// Default Import (ohne {})
import multiply from './utils.js';
console.log(multiply(4, 5)); // 20

// Alles importieren
import * as utils from './utils.js';
console.log(utils.add(1, 2));     // 3
console.log(utils.PI);            // 3.14
console.log(utils.default(2, 3)); // 6 (default export)

// Umbenennen
import { add as addNumbers } from './utils.js';
console.log(addNumbers(1, 2)); // 3

12. Class Syntax - OOP

ES6 bringt eine Class Syntax (syntactic sugar über Prototypes).

Classes in ES6
class User {
  // Constructor
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // Methods
  greet() {
    return `Hallo, ich bin ${this.name}`;
  }

  haveBirthday() {
    this.age++;
    return `Happy Birthday! Du bist jetzt ${this.age}`;
  }

  // Getter
  get info() {
    return `${this.name} (${this.age})`;
  }

  // Static method
  static create(name, age) {
    return new User(name, age);
  }
}

// Instanz erstellen
const user = new User('Anna', 25);
console.log(user.greet()); // 'Hallo, ich bin Anna'
console.log(user.info);    // 'Anna (25)'

// Static method
const user2 = User.create('Max', 30);

Class Inheritance

Class Vererbung
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    return `${this.name} macht ein Geräusch`;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Parent constructor aufrufen
    this.breed = breed;
  }

  // Override
  speak() {
    return `${this.name} bellt: Wuff!`;
  }

  // Neue Method
  fetch() {
    return `${this.name} apportiert den Ball`;
  }
}

const dog = new Dog('Bello', 'Golden Retriever');
console.log(dog.speak());  // 'Bello bellt: Wuff!'
console.log(dog.fetch());  // 'Bello apportiert den Ball'

📝 Quiz

Was ist der Unterschied zwischen Spread (...) und Rest (...)?

Tipps & Tricks

Arrow Functions - Wann NICHT nutzen?

// ❌ Nicht als Object Methods (kein eigenes this)
const user = {
  name: 'Anna',
  greet: () => {
    console.log(this.name); // undefined!
  }
};

// ✅ Normale Function oder Method Shorthand
const user = {
  name: 'Anna',
  greet() {
    console.log(this.name); // 'Anna'
  }
};

Destructuring mit Computed Keys

const key = 'userName';
const data = { userName: 'Anna', userAge: 25 };

// Destructuring mit computed key
const { [key]: name } = data;
console.log(name); // 'Anna'

Shallow Copy Warning

const original = {
  name: 'Anna',
  address: { city: 'Berlin' }
};

// ⚠️ Shallow copy - nested Objects werden referenziert!
const copy = { ...original };
copy.address.city = 'München';

console.log(original.address.city); // 'München' (auch verändert!)

// ✅ Deep copy für nested Objects
const deepCopy = JSON.parse(JSON.stringify(original));
// Oder: structuredClone(original) in modernen Browsern

Default Parameter mit Destructuring

function createUser({ name, age = 18, role = 'user' } = {}) {
  return { name, age, role };
}

// Mit = {} am Ende funktioniert auch ohne Argument:
createUser(); // { name: undefined, age: 18, role: 'user' }

Häufige Fehler

Fehler 1: Arrow Function ohne return

FALSCH:

const getUser = id => { id, name: 'Anna' };
// SyntaxError! {} wird als Code Block interpretiert

RICHTIG:

// Objekt in Klammern!
const getUser = id => ({ id, name: 'Anna' });

Fehler 2: Destructuring von undefined

FALSCH:

const user = undefined;
const { name } = user;
// TypeError: Cannot destructure property 'name' of 'undefined'

RICHTIG:

const user = undefined;
const { name } = user || {};
// Oder: const { name } = user ?? {};

Fehler 3: const vs let verwechseln

FALSCH:

const counter = 0;
counter++; // TypeError: Assignment to constant variable

RICHTIG:

let counter = 0;
counter++; // ✅

Fehler 4: Rest Parameter nicht am Ende

FALSCH:

function wrong(...rest, last) {
  // SyntaxError!
}

RICHTIG:

function correct(first, ...rest) {
  // ✅ Rest muss am Ende stehen
}
🎯

Zusammenfassung

Du hast gelernt:

  • ✅ Arrow Functions (=>) - Kürzere Syntax, kein eigenes this
  • ✅ Template Literals - String-Interpolation mit `$`
  • ✅ Destructuring - Werte aus Arrays/Objekten extrahieren
  • ✅ Spread (...) - Elemente verteilen/kopieren
  • ✅ Rest (...) - Argumente sammeln
  • ✅ Default Parameters - Standardwerte für Funktionen
  • ✅ Enhanced Object Literals - Objekte kürzer schreiben
  • ✅ Optional Chaining (?.) - Sicher auf Properties zugreifen
  • ✅ Nullish Coalescing (??) - Default nur bei null/undefined
  • ✅ let/const - Block Scope statt var
  • ✅ Modules - Import/Export für Code-Organisation
  • ✅ Classes - OOP Syntax

Key Takeaways:

  • Arrow Functions für kurze Callbacks, NICHT für Object Methods
  • Template Literals für String-Interpolation und Multiline
  • Destructuring macht Code kürzer und lesbarer
  • Spread/Rest haben gleiche Syntax, aber unterschiedliche Zwecke
  • Optional Chaining verhindert "Cannot read property of undefined"
  • const als Standard, let wenn Wert sich ändert, var vermeiden
  • Modules für bessere Code-Organisation

Best Practices:

  • Nutze arrow functions für Callbacks
  • Template literals statt String concatenation
  • Destructuring für übersichtlicheren Code
  • const als Standard, nur let wenn nötig
  • Optional chaining für sichere Property-Zugriffe

Praktische Übungen

Übung 1: Arrow Functions & Template Literals

Schreibe eine Funktion createGreeting, die Name und Alter nimmt und einen Begrüßungsstring zurückgibt:

createGreeting('Anna', 25);
// "Hallo Anna, du bist 25 Jahre alt!"

Übung 2: Destructuring

Gegeben:

const user = {
  id: 1,
  name: 'Anna',
  email: 'anna@example.com',
  address: {
    city: 'Berlin',
    zip: '10115'
  }
};

Extrahiere: name, email und city mit Destructuring.

Übung 3: Spread & Rest

  1. Kombiniere zwei Arrays: [1, 2, 3] und [4, 5, 6]
  2. Erstelle eine Funktion multiply, die beliebig viele Zahlen multipliziert

Übung 4: Optional Chaining

Gegeben:

const data = {
  user: {
    name: 'Anna',
    posts: [
      { title: 'Post 1', comments: [{ text: 'Nice!' }] }
    ]
  }
};

Greife sicher auf den ersten Comment des ersten Posts zu.

Übung 5: Real-World Beispiel

Erstelle eine formatUser Funktion mit:

  • Destructuring für Parameter
  • Default values
  • Template literals
  • Optional chaining
formatUser({
  name: 'Anna',
  age: 25,
  address: { city: 'Berlin' }
});
// "Anna (25) aus Berlin"

formatUser({ name: 'Max' });
// "Max (N/A) aus N/A"

Nächste Schritte

Du kennst jetzt Modern JavaScript!

Erweitere dein Wissen:

  • 🔷 TypeScript - Typsicheres JavaScript für große Projekte
  • ⚛️ React - Moderne UI-Development mit Components
  • 🅰️ Angular - Full-Featured Framework
JavaScriptLektion 14 von 17
82% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "JavaScript ES6+ Features - Moderne JavaScript Syntax" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten