Start · Sprachen · JavaScript · Referenz · SharedArrayBuffer[Symbol.species]

SharedArrayBuffer[Symbol.species]

Eigenschaft

Statischer Getter, der den Konstruktor liefert, mit dem <code>SharedArrayBuffer</code>-Methoden wie <code>slice()</code> ihre neuen Puffer-Objekte erzeugen.

seit JavaScript ES2017 (Browser: nur in cross-origin-isolierten Ko Kategorie: method-property

Signatur

get SharedArrayBuffer[Symbol.species]

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

Typ
Function
Beschreibung
Der Wert von 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);
true function undefined

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());
true true TaggedBuffer mit 4 Bytes

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);
false SharedArrayBuffer 8

// Wichtig · Fallstricke

  • Verfügbarkeit im Browser: SharedArrayBuffer gibt es nur in cross-origin-isolierten Seiten. Dafür müssen die HTTP-Header Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp gesetzt sein. Ob das zutrifft, zeigt self.crossOriginIsolated. Sonst ist SharedArrayBuffer nicht definiert und der Zugriff löst einen ReferenceError aus. In Node.js steht die Klasse immer zur Verfügung.
  • Strenge Prüfungen in slice(): Der Species-Konstruktor muss ein echtes SharedArrayBuffer-Objekt liefern, und zwar nicht denselben Puffer wie das Original. Außerdem muss es mindestens so groß sein wie angefordert. Andernfalls wirft slice() einen TypeError. Ein Species-Konstruktor, der zum Beispiel einen ArrayBuffer zurückgibt, funktioniert also nicht.
  • Gibt der Getter undefined oder null zurück, verwendet slice() wieder den Standard-Konstruktor SharedArrayBuffer.
  • Die Eigenschaft hat keinen Setter. Eine einfache Zuweisung wie MyBuf[Symbol.species] = X wird ignoriert, im Strict Mode gibt es einen TypeError. Zum Überschreiben nutzt man einen static get [Symbol.species]() oder Object.defineProperty.
  • Symbol.species gilt als Hindernis für Leistung und Sicherheit, weil Nutzercode in eingebaute Methoden eingreifen kann. Neue eingebaute Methoden (etwa toSorted() bei Arrays) werten es bewusst nicht mehr aus. Für neuen Code sollte man sich möglichst nicht darauf verlassen.