Der Array-Konstruktor ist eine eingebaute Funktion zur Array-Erzeugung — als Alternative zur Literalsyntax []. Er kann mit oder ohne new aufgerufen werden (new Array() und Array() sind äquivalent) und akzeptiert null, ein oder mehrere Argumente. Die berüchtigte Falle: bei genau einem numerischen Argument wird die Zahl als length interpretiert, nicht als Element — new Array(5) liefert ein sparse Array der Länge 5, nicht [5]. Seit ES2015 löst Array.of() dieses Inkonsistenz-Problem. In modernem Code ist das Literal [] der erste Wahl; der Konstruktor bleibt für dynamische Längen und Sparse-Array-Konstruktion relevant.
Drei Aufruf-Formen
Array() verhält sich je nach Anzahl der Argumente unterschiedlich.
// 1. Ohne Argument: leeres Array
const a = new Array();
console.log(a, a.length); // [] 0
// 2. Mit EINEM numerischen Argument: sparse Array dieser Länge
const b = new Array(3);
console.log(b, b.length); // [ <3 empty items> ] 3
console.log(0 in b); // false — kein echtes Element
// 3. Mit MEHREREN Argumenten oder nicht-numerisch: Elemente direkt
const c = new Array(1, 2, 3);
console.log(c); // [1, 2, 3]
const d = new Array('hi');
console.log(d); // ['hi'][] 0
[ <3 empty items> ] 3
false
[ 1, 2, 3 ]
[ 'hi' ]Diese Verzweigung beim einzigen numerischen Argument ist die Wurzel fast aller Konfusion rund um den Array-Konstruktor.
Sparse Arrays — Löcher statt Werte
Ein Array mit „leeren Plätzen" ist sparse — die length ist hochgesetzt, aber an den Positionen existiert kein eigener Property-Eintrag. Das hat subtile Konsequenzen.
const sparse = new Array(3);
console.log(sparse.length); // 3
console.log(sparse[0]); // undefined
console.log(0 in sparse); // false — Loch, kein Eintrag
// forEach überspringt Löcher!
sparse.forEach((v, i) => console.log('Index', i));
// → Keine Ausgabe — alle drei sind Löcher
// map auch — Löcher bleiben Löcher
const verdoppelt = sparse.map(x => x * 2);
console.log(verdoppelt); // [ <3 empty items> ]
// for-of ITERIERT aber über sie (liefert undefined)
for (const x of sparse) console.log('Iter:', x);3
undefined
false
Iter: undefined
Iter: undefined
Iter: undefinedDas unterschiedliche Verhalten von forEach (überspringt Löcher) und for-of (iteriert sie) ist eine berüchtigte Falle. Daher: sparse Arrays nur bewusst und mit Plan einsetzen.
Array.of() — die saubere Alternative (ES2015)
Array.of() behandelt jedes Argument als Element, egal Anzahl oder Typ. Damit verschwindet die Konstruktor-Inkonsistenz.
// Konstruktor — Falle bei einer Zahl
console.log(new Array(3)); // [ <3 empty items> ]
// Array.of — immer als Element
console.log(Array.of(3)); // [3]
console.log(Array.of(1, 2, 3)); // [1, 2, 3]
console.log(Array.of('hi')); // ['hi']
console.log(Array.of()); // [][ <3 empty items> ]
[ 3 ]
[ 1, 2, 3 ]
[ 'hi' ]
[]In Code, der eine variable Anzahl von Argumenten in ein Array packen soll, ist Array.of(...args) die korrekte Form. Pre-ES2015 musste man [].concat(args) oder ähnliche Tricks nutzen.
Vorbefüllen mit fill()
Ein sparse Array per Konstruktor + fill() ist das schnelle Pattern, ein Array bestimmter Länge mit demselben Wert vorzubereiten.
// Schnell: 10 Nullen
const nullen = new Array(10).fill(0);
console.log(nullen);
// 5 leere Arrays — Achtung: ALLE zeigen auf DASSELBE Array!
const matrix = new Array(3).fill([]);
matrix[0].push('A');
console.log(matrix); // alle drei haben 'A'!
// Korrekt: pro Position eigene Instanz mit Array.from + Mapper
const matrix2 = Array.from({ length: 3 }, () => []);
matrix2[0].push('A');
console.log(matrix2); // nur erstes hat 'A'[
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
]
[ [ 'A' ], [ 'A' ], [ 'A' ] ]
[ [ 'A' ], [], [] ]Die fill-Falle: bei Objekten/Arrays als Füllwert wird die gleiche Referenz an jede Position gesetzt. Wer pro Position eine eigene Instanz braucht, muss Array.from({ length: n }, () => factory()) nutzen.
Mit new oder ohne — egal
Anders als bei klassischen Konstruktoren spielt new bei Array() keine Rolle.
const a = new Array(1, 2, 3);
const b = Array(1, 2, 3);
console.log(a); // [1, 2, 3]
console.log(b); // [1, 2, 3]
console.log(a.constructor === b.constructor); // true[ 1, 2, 3 ]
[ 1, 2, 3 ]
trueDie Sprache definiert Array so, dass der Aufruf intern dasselbe macht, ob new davor steht oder nicht. Style-Guides empfehlen meist die kürzere Array(...)-Form.
Maximal-Länge
Die Spec erlaubt Arrays bis 2^32 - 1 Elemente (≈ 4,29 Milliarden). Negative oder nicht-ganzzahlige Zahlen werfen RangeError.
const max = 2 ** 32 - 1;
console.log('Max length:', max);
try {
new Array(-1);
} catch (e) {
console.log('Negativ:', e.message);
}
try {
new Array(1.5);
} catch (e) {
console.log('Float:', e.message);
}
try {
new Array(2 ** 32);
} catch (e) {
console.log('Zu groß:', e.message);
}Max length: 4294967295
Negativ: Invalid array length
Float: Invalid array length
Zu groß: Invalid array lengthIn der Praxis sind Arrays mit Millionen Elementen schon problematisch wegen Speicher und GC — der theoretische Maximalwert ist selten relevant.
Typed Array-Konstruktoren — andere Mechanik
Typed Arrays (Int8Array, Float32Array, etc.) haben eigene Konstruktoren mit eigener Semantik — kein direkter Bezug zum klassischen Array-Konstruktor.
// Mit Länge: direkt mit Nullen initialisiert (kein sparse-Verhalten)
const ints = new Int32Array(3);
console.log(ints); // Int32Array(3) [0, 0, 0]
console.log(0 in ints); // true — echte Werte
// Mit Array
const floats = new Float32Array([1.5, 2.5, 3.5]);
console.log(floats);
// Mit ArrayBuffer
const buf = new ArrayBuffer(8); // 8 Bytes
const view = new Uint8Array(buf);
view[0] = 255;
console.log(view);Int32Array(3) [ 0, 0, 0 ]
true
Float32Array(3) [ 1.5, 2.5, 3.5 ]
Uint8Array(8) [
255, 0, 0, 0,
0, 0, 0, 0
]Typed Arrays haben kein sparse-Verhalten — jedes Element ist initialisiert (mit dem Typ-spezifischen Null-Wert). Detail-Behandlung in einem eigenen Artikel.
Wann welche Form?
| Situation | Empfehlung |
|---|---|
| Bekannte Elemente, statisch | Literal: [1, 2, 3] |
| Variable Argument-Liste | Array.of(...args) |
Sparse Array für .fill(wert) | new Array(n).fill(wert) |
| Pro Position eigene Instanz | Array.from({length: n}, factory) |
| Iterable in Array konvertieren | Array.from(iterable) oder [...iterable] |
| Typed Array (Performance, Binärdaten) | new Int32Array(...) etc. |
Häufige Stolperfallen
new Array(3) ist NICHT [3]
Klassische Anfänger-Falle. new Array(3) liefert ein leeres sparse Array der Länge 3 — kein Array mit dem Wert 3 drin. Wer ein Single-Element-Array will: Array.of(3) oder [3].
fill() mit Object teilt Referenzen
new Array(3).fill([]) erzeugt drei Positionen, die ALLE auf dasselbe Array zeigen. Mutation an einem mutiert „alle". Lösung: Array.from({length: 3}, () => []) — der Mapper produziert pro Position eine neue Instanz.
forEach überspringt Löcher, for-of nicht
Sparse Arrays sind die Quelle subtiler Bugs. arr.forEach, arr.map, arr.filter überspringen Löcher — der Callback wird für sie nicht aufgerufen. for...of dagegen iteriert sie und liefert undefined. arr.length zählt sie mit.
Array.of seit ES2015 — die saubere Lösung
Array.of(...args) behandelt jedes Argument als Element, unabhängig von Anzahl oder Typ. Kein Sonder-Verhalten bei einer Zahl. In Code, der variable Argumente in ein Array packt, ist das die idiomatische Form.
new ist optional — Array() und new Array() identisch
Spec-Eigenschaft: der Konstruktor verhält sich mit und ohne new gleich. Style-Guides empfehlen meist die kürzere Form ohne new. Andere Konstruktoren wie Date oder Map haben dieses Verhalten NICHT — da ist new Pflicht.
Negative oder nicht-ganzzahlige Länge wirft RangeError
new Array(-1), new Array(1.5), new Array(NaN) alle: RangeError: Invalid array length. Wer dynamisch eine Länge berechnet, muss sicherstellen, dass das Resultat eine nicht-negative Ganzzahl im erlaubten Bereich ist.
Bei Realm-Übergang (iframes) hat jedes Realm seinen eigenen Array
Ein Array aus einem iframe ist NICHT instanceof Array im Parent-Realm — die Array-Konstruktoren sind getrennt. Robust: Array.isArray(x) nutzen, das funktioniert Realm-übergreifend.
Spread auf den Konstruktor: Array(...iter) hat keine sparse-Falle
Array(...iter) spreaded das Iterable in Argumente — mehrere Argumente, also kein Sonder-Verhalten. Praktisch äquivalent zu [...iter] oder Array.from(iter). Selten gesehen, weil die Alternativen lesbarer sind.