Start · Sprachen · JavaScript · Referenz · Symbol.isConcatSpreadable

Symbol.isConcatSpreadable

Eigenschaft

Wohlbekanntes Symbol, mit dem ein Objekt festlegt, ob <code>Array.prototype.concat()</code> es in seine einzelnen Elemente zerlegt oder als Ganzes anhängt.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Symbol.isConcatSpreadable

Beschreibung

Symbol.isConcatSpreadable ist eine statische, nicht beschreibbare Eigenschaft von Symbol. Ihr Wert ist ein wohlbekanntes Symbol, das Array.prototype.concat() abfragt. Für jedes Argument (und für this) prüft concat(), ob die Eigenschaft [Symbol.isConcatSpreadable] gesetzt ist. Bei einem truthy-Wert werden die Elemente einzeln angehängt, bei einem falsy-Wert (außer undefined) wird das Objekt als ein einziges Element eingefügt.

Ist die Eigenschaft undefined, gilt das Standardverhalten: Echte Arrays (Array.isArray() ergibt true) werden aufgelöst, alle anderen Objekte, auch array-ähnliche Objekte wie arguments oder NodeList, werden als Ganzes eingefügt.

In der Praxis braucht man das Symbol vor allem in zwei Fällen:

  • Ein Array soll bei concat() nicht aufgelöst werden, sondern verschachtelt bleiben.
  • Ein array-ähnliches Objekt oder eine eigene Collection-Klasse soll sich bei concat() wie ein Array verhalten.

Als Symbol selbst ist es kein Aufruf. Man verwendet es als berechneten Eigenschaftsschlüssel, zum Beispiel obj[Symbol.isConcatSpreadable] = true oder als Getter static/get [Symbol.isConcatSpreadable]() in einer Klasse.

Rückgabewert

Typ
symbol
Beschreibung
Das wohlbekannte Symbol Symbol.isConcatSpreadable. Eigenschafts-Attribute: writable: false, enumerable: false, configurable: false.

Beispiele

Array bei concat() nicht auflösen

const basis = [1, 2];
const paar = [3, 4];

// Standard: paar wird aufgelöst
console.log(basis.concat(paar));

// Mit false bleibt paar ein verschachteltes Array
paar[Symbol.isConcatSpreadable] = false;
console.log(basis.concat(paar));
[1, 2, 3, 4] [1, 2, [3, 4]]

Array-ähnliches Objekt auflösbar machen

const arrayAehnlich = {
  length: 2,
  0: 'rot',
  1: 'grün',
  [Symbol.isConcatSpreadable]: true
};

const farben = ['blau'].concat(arrayAehnlich);
console.log(farben);
['blau', 'rot', 'grün']

Eigene Collection-Klasse

class Warenkorb {
  #artikel = [];
  add(name) {
    this[this.#artikel.length] = name;
    this.#artikel.push(name);
    return this;
  }
  get length() {
    return this.#artikel.length;
  }
  get [Symbol.isConcatSpreadable]() {
    return true;
  }
}

const korb = new Warenkorb().add('Brot').add('Milch');
const alles = ['Äpfel'].concat(korb, ['Käse']);
console.log(alles);
['Äpfel', 'Brot', 'Milch', 'Käse']

Bei arguments aktivieren

function sammle() {
  arguments[Symbol.isConcatSpreadable] = true;
  return [0].concat(arguments);
}

console.log(sammle(1, 2, 3));
[0, 1, 2, 3]

// Wichtig · Fallstricke

  • Das Symbol wirkt nur auf Array.prototype.concat(). Spread-Syntax ([...x]), Array.from() und flat() werten es nicht aus. Spread nutzt stattdessen Symbol.iterator.
  • Ein aufgelöstes Nicht-Array braucht eine sinnvolle length-Eigenschaft. Fehlt sie, wird sie als 0 behandelt und es werden keine Elemente übernommen. Lücken bleiben als leere Plätze („holes“) erhalten.
  • Das Symbol wird auch für this ausgewertet: arr[Symbol.isConcatSpreadable] = false; arr.concat(5) ergibt [arr, 5].
  • Das Symbol an Array.prototype zu setzen, ändert das Verhalten global. Das ist ein Anti-Pattern, verwirrt Bibliotheken und kann Engine-Optimierungen von concat() ausbremsen.
  • Kompatibilität: in allen modernen Browsern und Node.js 6+ verfügbar, nicht im Internet Explorer.