Signatur
Beschreibung
AsyncGeneratorFunction.prototype.prototype ist das interne Objekt %AsyncGeneratorPrototype%, das auch unter dem Namen AsyncGenerator.prototype bekannt ist. Dort sind die Methoden next(), return() und throw() definiert, die jedes asynchrone Generator-Objekt bereitstellt. Außerdem liegt dort das Symbol Symbol.toStringTag mit dem Wert "AsyncGenerator".
Die Vererbungskette hat drei Stufen: Jede mit async function* deklarierte Funktion bekommt ihr eigenes prototype-Objekt. Dessen [[Prototype]] ist AsyncGeneratorFunction.prototype.prototype. Ruft man die Generatorfunktion auf, erbt das zurückgegebene Generator-Objekt von fn.prototype und damit indirekt von diesem gemeinsamen Objekt.
Da AsyncGeneratorFunction kein globaler Bezeichner ist, kommt man über (async function* () {}).constructor an das Objekt heran. Das braucht man vor allem für Introspektion, zum Prüfen, ob ein Objekt ein asynchroner Generator ist, oder für Polyfills und Tests. Im normalen Anwendungscode greift man selten direkt darauf zu.
Rückgabewert
AsyncGenerator.prototype mit den Methoden next(), return() und throw(). Eigenschafts-Attribute: writable: false, enumerable: false, configurable: true.Beispiele
An den gemeinsamen Prototyp herankommen
// AsyncGeneratorFunction ist nicht global – über den Konstruktor holen
const AsyncGeneratorFunction = (async function* () {}).constructor;
const AsyncGeneratorPrototype = AsyncGeneratorFunction.prototype.prototype;
console.log(Object.prototype.toString.call(AsyncGeneratorPrototype));
console.log(Object.getOwnPropertyNames(AsyncGeneratorPrototype));
Prototypkette eines asynchronen Generators nachvollziehen
const AsyncGeneratorPrototype = (async function* () {}).constructor.prototype.prototype;
async function* ladeSeiten() {
yield 'Seite 1';
yield 'Seite 2';
}
const it = ladeSeiten();
console.log(Object.getPrototypeOf(it) === ladeSeiten.prototype);
console.log(Object.getPrototypeOf(ladeSeiten.prototype) === AsyncGeneratorPrototype);
console.log(it.next === AsyncGeneratorPrototype.next);
Prüfen, ob ein Objekt ein asynchroner Generator ist
const AsyncGeneratorPrototype = (async function* () {}).constructor.prototype.prototype;
const isAsyncGenerator = (obj) =>
obj !== null && typeof obj === 'object' && AsyncGeneratorPrototype.isPrototypeOf(obj);
async function* stream() { yield 1; }
function* syncGen() { yield 1; }
console.log(isAsyncGenerator(stream()));
console.log(isAsyncGenerator(syncGen()));
console.log(isAsyncGenerator({ next: async () => ({}) }));
Eigenschafts-Attribute auslesen
const AsyncGeneratorFunction = (async function* () {}).constructor;
const { writable, enumerable, configurable } =
Object.getOwnPropertyDescriptor(AsyncGeneratorFunction.prototype, 'prototype');
console.log({ writable, enumerable, configurable });
// Wichtig · Fallstricke
- Nicht verwechseln:
AsyncGeneratorFunction.prototypeist der Prototyp der Generatorfunktionen.AsyncGeneratorFunction.prototype.prototypeist der Prototyp, von dem dieprototype-Objekte dieser Funktionen erben, also die Grundlage für die Generator-Objekte. - Die Eigenschaft ist
writable: false. Eine Zuweisung wird im nicht-strikten Modus stillschweigend ignoriert und löst im strikten Modus einenTypeErroraus. - Methoden, die man hier ergänzt (Monkey-Patching), stehen in allen asynchronen Generatoren der Laufzeitumgebung zur Verfügung. Das kann mit künftigen Standardmethoden kollidieren und sollte nur bei Polyfills passieren.
- Die Prüfung mit
isPrototypeOffunktioniert nur innerhalb desselben Realms. Generatoren aus einem iframe oder einem anderenvm-Kontext haben einen anderen Prototyp. - Ein selbst gebauter asynchroner Iterator (ein Objekt mit
next()undSymbol.asyncIterator) erbt nicht von diesem Prototyp. Fürfor await...ofreicht das Iterator-Protokoll. - Wird seit ES2018 unterstützt: Chrome 63+, Firefox 55+, Safari 12+, Node.js 10+.