JavaScript Prototypen und Vererbung | Enjyn Gruppe
Hallo Welt
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

235 Dokumentationen verfügbar

Wissensdatenbank

JavaScript Prototypen Vererbung

Zuletzt aktualisiert: 20.01.2026 um 11:25 Uhr

JavaScript Prototypen und Vererbung

JavaScript verwendet prototypbasierte Vererbung statt klassenbasierter. Verstehen Sie die Prototype Chain und moderne Klassen-Syntax.

Prototype Chain Basics

// Jedes Objekt hat einen internen [[Prototype]]
const obj = { name: 'Test' };

// Zugriff via __proto__ (veraltet) oder Object.getPrototypeOf()
console.log(Object.getPrototypeOf(obj) === Object.prototype);  // true

// Die Prototype Chain
// obj → Object.prototype → null

const arr = [1, 2, 3];
// arr → Array.prototype → Object.prototype → null

function greet() {}
// greet → Function.prototype → Object.prototype → null

Visualisierung

┌─────────────────────────────────────────────────────────────┐
│                    PROTOTYPE CHAIN                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   const person = { name: 'Max' };                           │
│                                                             │
│   ┌──────────────┐                                          │
│   │    person    │                                          │
│   │ name: 'Max'  │                                          │
│   └──────┬───────┘                                          │
│          │ [[Prototype]]                                    │
│          ▼                                                  │
│   ┌──────────────────────────┐                              │
│   │    Object.prototype      │                              │
│   │ toString()               │                              │
│   │ hasOwnProperty()         │                              │
│   │ valueOf()                │                              │
│   └──────────┬───────────────┘                              │
│              │ [[Prototype]]                                │
│              ▼                                              │
│           null                                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Konstruktor-Funktionen (alt)

// Vor ES6: Konstruktor-Funktionen
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// Methoden auf dem Prototype (geteilt von allen Instanzen)
Person.prototype.greet = function() {
    return `Hallo, ich bin ${this.name}`;
};

Person.prototype.birthday = function() {
    this.age++;
};

// Instanz erstellen
const max = new Person('Max', 30);
const anna = new Person('Anna', 25);

max.greet();  // "Hallo, ich bin Max"
anna.greet(); // "Hallo, ich bin Anna"

// Beide teilen dieselbe greet-Funktion!
console.log(max.greet === anna.greet);  // true

ES6 Klassen (modern)

// ES6 Klassen sind "syntactic sugar" über Prototypen
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    // Instanz-Methode (auf Prototype)
    greet() {
        return `Hallo, ich bin ${this.name}`;
    }

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

    // Setter
    set info(value) {
        [this.name, this.age] = value.split(', ');
    }

    // Statische Methode (auf der Klasse selbst)
    static create(name, age) {
        return new Person(name, age);
    }
}

const max = new Person('Max', 30);
max.greet();        // "Hallo, ich bin Max"
max.info;           // "Max, 30 Jahre"
Person.create('Anna', 25);  // Statische Methode

Vererbung mit extends

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

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

class Dog extends Animal {
    constructor(name, breed) {
        super(name);  // MUSS vor this aufgerufen werden!
        this.breed = breed;
    }

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

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

class Cat extends Animal {
    speak() {
        // super.speak() aufrufen + erweitern
        return `${super.speak()}: Miau!`;
    }
}

const dog = new Dog('Bello', 'Labrador');
dog.speak();  // "Bello bellt: Wuff!"
dog.fetch();  // "Bello holt den Ball"

const cat = new Cat('Minka');
cat.speak();  // "Minka macht ein Geräusch: Miau!"

Object.create() für Vererbung

// Objekt mit spezifischem Prototype erstellen
const personProto = {
    greet() {
        return `Hallo, ich bin ${this.name}`;
    },
    introduce() {
        return `${this.name}, ${this.age} Jahre alt`;
    }
};

// Neues Objekt mit personProto als Prototype
const max = Object.create(personProto);
max.name = 'Max';
max.age = 30;

max.greet();      // "Hallo, ich bin Max"
max.introduce();  // "Max, 30 Jahre alt"

// Mit Property Descriptors
const anna = Object.create(personProto, {
    name: { value: 'Anna', writable: true },
    age: { value: 25, writable: true }
});

Prototype-Manipulation

// Prototype von bestehendem Objekt ändern (NICHT empfohlen!)
const obj = { a: 1 };
const proto = { b: 2 };

Object.setPrototypeOf(obj, proto);
console.log(obj.b);  // 2

// Besser: Object.create von Anfang an nutzen
const obj2 = Object.create(proto);
obj2.a = 1;

// Prototype-Kette prüfen
console.log(proto.isPrototypeOf(obj2));  // true

// Eigene Property vs. geerbte Property
console.log(obj2.hasOwnProperty('a'));  // true (eigene)
console.log(obj2.hasOwnProperty('b'));  // false (geerbt)
console.log('b' in obj2);               // true (irgendwo in der Kette)

Private Felder (ES2022)

class BankAccount {
    // Private Felder mit #
    #balance = 0;
    #transactions = [];

    constructor(initialBalance) {
        this.#balance = initialBalance;
    }

    deposit(amount) {
        if (amount > 0) {
            this.#balance += amount;
            this.#logTransaction('deposit', amount);
        }
    }

    withdraw(amount) {
        if (amount > 0 && amount <= this.#balance) {
            this.#balance -= amount;
            this.#logTransaction('withdraw', amount);
            return amount;
        }
        throw new Error('Nicht genug Guthaben');
    }

    // Private Methode
    #logTransaction(type, amount) {
        this.#transactions.push({ type, amount, date: new Date() });
    }

    get balance() {
        return this.#balance;
    }
}

const account = new BankAccount(100);
account.deposit(50);
account.balance;      // 150
// account.#balance;  // SyntaxError! Privat!

Mixins für mehrfache Vererbung

// JavaScript hat keine echte Mehrfachvererbung
// Lösung: Mixins

const CanFly = {
    fly() {
        return `${this.name} fliegt`;
    }
};

const CanSwim = {
    swim() {
        return `${this.name} schwimmt`;
    }
};

const CanWalk = {
    walk() {
        return `${this.name} läuft`;
    }
};

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

// Mixins anwenden
class Duck extends Animal {}
Object.assign(Duck.prototype, CanFly, CanSwim, CanWalk);

const donald = new Duck('Donald');
donald.fly();   // "Donald fliegt"
donald.swim();  // "Donald schwimmt"
donald.walk();  // "Donald läuft"

instanceof und Typprüfung

class Animal {}
class Dog extends Animal {}

const dog = new Dog();

// instanceof prüft die Prototype-Kette
console.log(dog instanceof Dog);     // true
console.log(dog instanceof Animal);  // true
console.log(dog instanceof Object);  // true

// Konstruktor prüfen
console.log(dog.constructor === Dog);  // true

// Symbol.hasInstance für eigene instanceof-Logik
class Even {
    static [Symbol.hasInstance](obj) {
        return typeof obj === 'number' && obj % 2 === 0;
    }
}

console.log(4 instanceof Even);   // true
console.log(5 instanceof Even);   // false
💡 Best Practice: Nutzen Sie ES6 Klassen für bessere Lesbarkeit. Vermeiden Sie das Ändern von eingebauten Prototypen (z.B. Array.prototype). Für echte Kapselung verwenden Sie private Felder (#) statt Closures.

Weitere Informationen

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120