Signatur
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
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));
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);
}
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);
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);
// Wichtig · Fallstricke
- Nur für
withrelevant: Die Eigenschaft wirkt sich ausschließlich auf die Auflösung von Bezeichnern inwith-Blöcken aus. Normale Zugriffe wiearr.keys()bleiben unberührt. - Strict Mode und Module:
withlöst dort einenSyntaxErroraus. Beispiele mitwithlaufen 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
atodertoSorted, sollte ihren Namen auch inArray.prototype[Symbol.unscopables]eintragen, damit sich der Polyfill wie die native Methode verhält. - Die Liste wächst: Mit ES2019 kamen
flat/flatMap, mit ES2022at, mit ES2023findLast,findLastIndex,toReversed,toSortedundtoSplicedhinzu. Ältere Engines haben entsprechend kürzere Listen. - Der Prototyp ist
null. Geerbte Schlüssel wietoStringwerden also nicht versehentlich ausgeblendet.