Array
Array is a global constructor for creating list-like objects with a dynamic length. Every array inherits from Array.prototype, which provides a large set of instance methods for traversal, mutation, and transformation.
Constructor
Call Array() with elements to create a list, or with a single numeric argument to create a sparse list with a given length:
new Array(); // []
new Array(1, 2, 3); // [1, 2, 3]
new Array(3); // [empty × 3] — sparse, length 3
new Array("foo"); // ["foo"]
Without new, the behavior is identical. Array literals [1, 2, 3] never trigger the length behavior, so they are generally preferred. When you do use the constructor, watch out for invalid length arguments — they throw immediately instead of producing a malformed list.
The constructor throws a RangeError for non-integer or out-of-bounds lengths:
new Array(-1); // RangeError: Invalid array length
new Array(4.5); // RangeError: Invalid array length
new Array(2 ** 32); // RangeError: Invalid array length
Static Methods
The constructor handles creation, but Array also exposes several static utilities for type checking and constructing new instances from various sources. These methods work without a receiver — you call them directly on the Array object itself.
Array.isArray(value)
Returns true if value is an Array; false otherwise. Uses a brand check against a private field, so it works reliably across realms such as iframes and Web Workers where instanceof Array would fail.
Array.isArray([]); // true
Array.isArray(new Array(5)); // true
Array.isArray(Array.prototype); // true — Array.prototype is itself an array
Array.isArray({}); // false
Array.isArray(new Uint8Array(32)); // false — TypedArrays are not Arrays
The brand check makes isArray the most dependable way to confirm you are dealing with a real list, especially in library code that might receive values from unknown origins. Once you have confirmed the type, the next common need is building a new array from data that is not yet in array form.
Array.from(items[, mapFn[, thisArg]])
Creates a new shallow-copied Array from an iterable or array-like object. Added in ES6.
Array.from("foo"); // ["f", "o", "o"]
Array.from(new Set([1, 2, 2, 3])); // [1, 2, 3]
const m = new Map([["a", 1], ["b", 2]]);
Array.from(m.values()); // [1, 2]
// With map function
Array.from([1, 2, 3], x => x * x); // [1, 4, 9]
The from() method accepts any iterable — strings, Sets, Maps, or generator functions — and returns a flat list. You can also pass a mapping function as the second argument to transform each element during construction, which avoids a separate .map() call.
The method is generic. Call it on any constructor to produce instances of that class:
Array.from.call(Set, [1, 2, 3]); // Set { 1, 2, 3 }
Unlike from(), which pulls data out of an existing source, of() lets you spell out each item explicitly. This is the method to reach for when you have a handful of known values and want to avoid the single-number-as-length pitfall of the constructor.
Array.of(element1[, element2[, …]])
Creates a new list from the passed arguments. Unlike the constructor, a single numeric argument is treated as an element, not a length:
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of(); // []
This makes Array.of() the predictable alternative to new Array(length). When your data arrives asynchronously — for example, from a stream of API responses — you need a method that can wait for each item to resolve before assembling the final list.
Array.fromAsync(items[, mapFn[, thisArg]])
Creates a new list from an async iterable, iterable, or array-like. Returns a Promise that resolves to the finished product. Added in ES2024.
async function* gen() {
yield 1;
yield 2;
yield 3;
}
await Array.fromAsync(gen()); // [1, 2, 3]
// With map function
await Array.fromAsync([1, 2, 3], async x => x * x); // [1, 4, 9]
Key Gotchas
While the constructor and static methods are straightforward, a few behavioral quirks can catch you off guard — especially around sparseness, type checking across realms, and the single-argument trap.
Sparse arrays. new Array(3) creates a list with length: 3 but no own properties at any index. Accessing an index returns undefined, but the property does not exist. So 0 in arr is false. Methods like .map() skip empty slots.
const a = new Array(3);
a.length; // 3
0 in a; // false
a[0]; // undefined
a.map(x => x); // [<3 empty items>] — skips empty slots
Constructor vs literal. The constructor and bracket syntax produce different results for a single number argument, which has caused subtle bugs in code that dynamically passes a count to new Array(). When you see a numeric argument, always check whether the code intends a sparse list of that length or a single-element list containing that number.
new Array(3); // [empty × 3]
[3]; // [3]
RangeError on large lengths. The constructor throws instead of silently failing for lengths at or beyond 2 ** 32.
instanceof fails across realms. If you need to check whether a value is an array and it might come from another JavaScript global (an iframe, a Web Worker, a different JS engine), use Array.isArray() instead of instanceof Array.
See Also
- Array.prototype.filter() — Create a new array with elements that pass a test
- Array.prototype.map() — Transform each element of an array
- Array.prototype.reduce() — Reduce an array to a single value
- Array.isArray() — Check whether a value is an array
- Array.of() — Create arrays from arguments reliably