Working of Arrays in JavaScript
1. Introduction
In JavaScript, arrays are powerful and flexible data structures that allow you to store multiple values in a single variable. However, under the hood, JavaScript arrays behave differently compared to traditional arrays in languages like C or C++.
2. Array Storage in JavaScript vs C/C++
Traditional Arrays (C/C++)
- Items are stored at contiguous memory locations.
- Each element has the same data type and size.
- Allows for true random access by calculating memory offsets.
JavaScript Arrays
- Items are references stored at contiguous memory locations, not actual values.
- Allows storing elements of different types (number, string, boolean, object, etc.).
- The array is more like a dynamic object with indexed properties.
3. Random Access in Arrays
Random access means accessing any element in constant time O(1)
.
Example:
const arr = [10, 20, 'hello', true];
console.log(arr[1]); // Output: 20
Explanation:
- Base Address + (Index * Size of Reference) = Address of element
- Since references are of the same size, calculating access position is straightforward.
4. Advantages of Arrays
1. Random Access
- Direct access to elements using index.
- Efficient
O(1)
time complexity.
2. Cache Friendliness
- Contiguous reference storage improves cache locality.
- Nearby elements are likely to be prefetched into the CPU cache, enhancing performance.
5. Disadvantages of Arrays
1. Insertion/Deletion
- Inserting or deleting at the beginning/middle requires shifting elements.
- Time complexity is
O(n)
.
const arr = [1, 2, 3];
arr.unshift(0); // Insert at start (O(n))
arr.shift(); // Remove first element (O(n))
2. Search (for unsorted data)
- Linear search in
O(n)
for unsorted data.
const arr = [5, 3, 7, 1];
console.log(arr.includes(7)); // true (Linear search)
6. Dynamic Sized Arrays in JavaScript
JavaScript arrays automatically resize themselves.
Behind the Scenes:
- When array is created, it allocates extra memory.
- Once full, it doubles (or increases) the memory, copies the old elements, and appends the new one.
let arr = [];
for (let i = 0; i < 1000; i++) {
arr.push(i); // Still O(1) on average
}
Amortized Time Complexity:
- Inserting
n
items takesO(n)
overall. - Average time per insertion:
O(1)
.
7. JavaScript Array Internals
- Arrays in JavaScript are objects.
- They have special properties like
.length
, and methods:.push()
,.pop()
,.shift()
,.unshift()
.
let arr = [1, 2, 3];
console.log(arr.length); // 3
8. Performance of Array Methods
Operation | Time Complexity | Description |
---|---|---|
push() | O(1) Amortized | Add to end |
pop() | O(1) | Remove from end |
unshift() | O(n) | Add to beginning |
shift() | O(n) | Remove from beginning |
index access | O(1) | Random access |
includes()/search | O(n) | Search by value |
9. When Not to Use Arrays
Arrays are not always the best data structure:
- For frequent insertion/deletion: Use Linked List.
- For fast search, insert, delete: Use Hash Table.
10. Visual Summary
JavaScript Array Memory Model
[ Reference ] [ Reference ] [ Reference ]
| | |
v v v
[Number] [String] [Boolean]
Dynamic Array Resizing
Initial: [1, 2, 3] + 2 empty slots
After push(4,5): [1,2,3,4,5]
After push(6): Resize to [1,2,3,4,5,6,_,_,_]
11. Conclusion
JavaScript arrays are flexible, dynamic, and optimized for general-purpose use. They offer great performance benefits like random access and cache-friendliness but come with trade-offs in insertion/deletion performance. Understanding how arrays work internally helps you make informed decisions about when and how to use them efficiently.
Tip: For performance-critical apps, analyze access and mutation patterns to decide the best data structure (Array, Object, Map, Set, Linked List, etc.).