Signatur
Beschreibung
SharedArrayBuffer[Symbol.species] ist eine statische Zugriffs-Eigenschaft (nur Getter), die standardmäßig einfach this zurückgibt, also den Konstruktor, über den sie aufgerufen wird. Bei SharedArrayBuffer selbst ist das SharedArrayBuffer, bei einer Unterklasse die Unterklasse.
Gebraucht wird die Eigenschaft intern von SharedArrayBuffer.prototype.slice(). Die Methode bestimmt über den sogenannten Species-Konstruktor, welche Klasse der zurückgegebene Puffer bekommt. Erbt eine eigene Klasse von SharedArrayBuffer, gibt slice() deshalb automatisch wieder eine Instanz dieser Unterklasse zurück.
Braucht man das nicht, weil die Unterklasse zum Beispiel zusätzliche Konstruktor-Parameter erwartet oder Kopien wieder schlichte SharedArrayBuffer sein sollen, überschreibt man in der Unterklasse den statischen Getter [Symbol.species]. Im Alltag greift man selten direkt darauf zu. Die Eigenschaft ist vor allem beim Schreiben eigener Unterklassen und in Bibliotheken wichtig.
Rückgabewert
this, also der Konstruktor, über den der Getter aufgerufen wurde. Standardmäßig SharedArrayBuffer, bei Unterklassen die jeweilige Unterklasse (außer sie überschreibt den Getter).Beispiele
Standardwert prüfen
// Der Getter gibt den Konstruktor selbst zurück
console.log(SharedArrayBuffer[Symbol.species] === SharedArrayBuffer);
// Eigenschafts-Deskriptor: nur Getter, kein Setter
const desc = Object.getOwnPropertyDescriptor(SharedArrayBuffer, Symbol.species);
console.log(typeof desc.get, desc.set);
Unterklasse: slice() behält den eigenen Typ
class TaggedBuffer extends SharedArrayBuffer {
describe() {
return `TaggedBuffer mit ${this.byteLength} Bytes`;
}
}
const buf = new TaggedBuffer(16);
const part = buf.slice(0, 4);
console.log(TaggedBuffer[Symbol.species] === TaggedBuffer);
console.log(part instanceof TaggedBuffer);
console.log(part.describe());
Species überschreiben, damit slice() einen einfachen SharedArrayBuffer liefert
class WorkerBuffer extends SharedArrayBuffer {
// slice() soll einfache SharedArrayBuffer erzeugen
static get [Symbol.species]() {
return SharedArrayBuffer;
}
}
const shared = new WorkerBuffer(32);
const copy = shared.slice(8, 16);
console.log(copy instanceof WorkerBuffer);
console.log(copy.constructor.name, copy.byteLength);
// Wichtig · Fallstricke
- Verfügbarkeit im Browser:
SharedArrayBuffergibt es nur in cross-origin-isolierten Seiten. Dafür müssen die HTTP-HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corpgesetzt sein. Ob das zutrifft, zeigtself.crossOriginIsolated. Sonst istSharedArrayBuffernicht definiert und der Zugriff löst einenReferenceErroraus. In Node.js steht die Klasse immer zur Verfügung. - Strenge Prüfungen in
slice(): Der Species-Konstruktor muss ein echtesSharedArrayBuffer-Objekt liefern, und zwar nicht denselben Puffer wie das Original. Außerdem muss es mindestens so groß sein wie angefordert. Andernfalls wirftslice()einenTypeError. Ein Species-Konstruktor, der zum Beispiel einenArrayBufferzurückgibt, funktioniert also nicht. - Gibt der Getter
undefinedodernullzurück, verwendetslice()wieder den Standard-KonstruktorSharedArrayBuffer. - Die Eigenschaft hat keinen Setter. Eine einfache Zuweisung wie
MyBuf[Symbol.species] = Xwird ignoriert, im Strict Mode gibt es einenTypeError. Zum Überschreiben nutzt man einenstatic get [Symbol.species]()oderObject.defineProperty. Symbol.speciesgilt als Hindernis für Leistung und Sicherheit, weil Nutzercode in eingebaute Methoden eingreifen kann. Neue eingebaute Methoden (etwatoSorted()bei Arrays) werten es bewusst nicht mehr aus. Für neuen Code sollte man sich möglichst nicht darauf verlassen.