Start · Sprachen · JavaScript · Referenz · Array.prototype[Symbol.unscopables]

Array.prototype[Symbol.unscopables]

Eigenschaft

Objekt ohne Prototyp, das Array-Methodennamen auflistet, die in einer <code>with</code>-Anweisung nicht als Variablen sichtbar werden sollen.

seit JavaScript ES2015 (Baseline: alle modernen Browser, Node.js 0 Kategorie: method-property

Signatur

Array.prototype[Symbol.unscopables]

Beschreibung

Array.prototype[Symbol.unscopables] ist eine Daten-Eigenschaft, die alle Array-Instanzen über die Prototypkette gemeinsam nutzen. Ihr Wert ist ein Objekt mit dem Prototyp null. Jede Eigenschaft darin mit dem Wert true nennt eine Array-Methode, die in einem with-Block nicht als Bezeichner aufgelöst wird.

Der Hintergrund ist Abwärtskompatibilität: Mit ES2015 und später kamen neue Methoden wie keys, values, entries, includes und flat hinzu. Alter Code wie with (arr) { keys.push(x) } hätte sonst plötzlich arr.keys statt der äußeren Variable keys verwendet. Die Unscopables-Liste verhindert das, damit bestehende Websites weiter funktionieren.

Enthalten sind aktuell (Stand ES2023/ES2024): at, copyWithin, entries, fill, find, findIndex, findLast, findLastIndex, flat, flatMap, includes, keys, toReversed, toSorted, toSpliced und values. Ältere Methoden wie push, map oder length stehen nicht auf der Liste. Sie bleiben in with also sichtbar.

In der Praxis braucht man die Eigenschaft kaum, weil with im Strict Mode und in ES-Modulen verboten ist. Nützlich ist sie beim Verständnis von Engine-Verhalten, bei Polyfills für neue Array-Methoden und als Vorbild für eigene Klassen, die Symbol.unscopables selbst festlegen.

Rückgabewert

Typ
Object
Beschreibung
Ein Objekt mit dem Prototyp null, dessen Schlüssel Methodennamen sind und alle den Wert true haben. Eigenschafts-Attribute: writable: false, enumerable: false, configurable: true.

Beispiele

Liste der ausgeblendeten Methoden anzeigen

const unscopables = Array.prototype[Symbol.unscopables];

console.log(Object.keys(unscopables));
console.log(Object.getPrototypeOf(unscopables));
["at", "copyWithin", "entries", "fill", "find", "findIndex", "findLast", "findLastIndex", "flat", "flatMap", "includes", "keys", "toReversed", "toSorted", "toSpliced", "values"] null

Wirkung in einer with-Anweisung (nur Sloppy Mode, kein Modul)

// Läuft nur in klassischen Skripten ohne "use strict"
var values = ['äußere', 'Variable'];
var zahlen = [10, 20, 30];

with (zahlen) {
  // 'values' steht in den Unscopables -> äußere Variable wird verwendet
  console.log(values);
  // 'length' steht NICHT in den Unscopables -> zahlen.length
  console.log(length);
}
["äußere", "Variable"] 3

Eigenschafts-Deskriptor prüfen

const desc = Object.getOwnPropertyDescriptor(Array.prototype, Symbol.unscopables);

console.log(desc.writable, desc.enumerable, desc.configurable);
console.log('includes' in desc.value, 'map' in desc.value);
false false true true false

Eigene Klasse mit Symbol.unscopables

class Konfiguration {
  constructor() {
    this.name = 'App';
    this.debug = true;
  }
}

// 'name' soll in with-Blöcken nicht die äußere Variable verdecken
Konfiguration.prototype[Symbol.unscopables] = Object.assign(
  Object.create(null),
  { name: true }
);

console.log(Konfiguration.prototype[Symbol.unscopables].name);
true

// Wichtig · Fallstricke

  • Nur für with relevant: Die Eigenschaft wirkt sich ausschließlich auf die Auflösung von Bezeichnern in with-Blöcken aus. Normale Zugriffe wie arr.keys() bleiben unberührt.
  • Strict Mode und Module: with löst dort einen SyntaxError aus. Beispiele mit with laufen deshalb nur in klassischen Skripten im Sloppy Mode.
  • Nicht beschreibbar, aber konfigurierbar: Die Eigenschaft selbst ist writable: false. Das Objekt, auf das sie verweist, ist dagegen veränderbar. Es zu ändern gilt als schlechter Stil, weil es globales Verhalten verändert.
  • Polyfills: Wer eine neue Array-Methode nachrüstet, etwa at oder toSorted, sollte ihren Namen auch in Array.prototype[Symbol.unscopables] eintragen, damit sich der Polyfill wie die native Methode verhält.
  • Die Liste wächst: Mit ES2019 kamen flat/flatMap, mit ES2022 at, mit ES2023 findLast, findLastIndex, toReversed, toSorted und toSpliced hinzu. Ältere Engines haben entsprechend kürzere Listen.
  • Der Prototyp ist null. Geerbte Schlüssel wie toString werden also nicht versehentlich ausgeblendet.