JavaScript Prototype Methods: The Hidden Cost Behind Convenience

Chris was implementing a 'Queue' data structure.
A Queue is a First-In-First-Out (FIFO) structure, much like a waiting line where the first person to arrive is the first to leave.
"JavaScript arrays are the best. I can just push when inserting and shift when removing. Done!"
// ❌ Chris's Queue Implementation
const queue = [];
// Enqueue 100,000 items
for (let i = 0; i < 100000; i++) {
queue.push(i);
}
// Dequeue 100,000 items
while (queue.length > 0) {
queue.shift(); // Remove one from the front
}But something was strange. Inserting data with push finished in the blink of an eye, but removing data with shift took an incredibly long time.
Both are just one-line array methods, so why is the speed difference like night and day?
The reason is that every method has a different "Cost." Today, we will dig into the internal mechanics and the 'cost' of the JavaScript array methods we use without thinking.
1. Playing at the Back is Fast: push & pop
JavaScript arrays are stored sequentially in memory.
These operations do not need to touch the existing data standing in line. You just place a chair at the end or take one away.
Whether there is 1 item or 1 million items, the time it takes for this operation is roughly the same. This is called Constant Time (O(1)).
2. Touching the Front Opens the Gates of Hell: shift, unshift & splice
The problem arises when you touch the front or the middle of an array.
When Chris called queue.shift(), the following happened inside the JavaScript engine:
In other words, to delete one item from the front, you must move all remaining data one step forward (Re-indexing).
If there are N items, N move operations are required. This is called Linear Time (O(N)). Since Chris called shift 100,000 times, internally, roughly 100,000 × 100,000 move operations occurred. It has to be slow.
3. It's Not Magic: filter, map, slice, reduce
"Then wouldn't it be faster if I used filter or map instead of a loop?"
This is a common misconception among beginners.
// Keep only even numbers
const evens = numbers.filter(num => num % 2 === 0);This code is very short, but internally, it is ultimately a loop that iterates from index 0 to the end of the array.
If you put this code inside another loop? It immediately becomes the culprit of performance degradation. slice, reduce, and forEach are all the same. They are just Syntactic Sugar, not magic wands.
4. JavaScript Array Method Cost Cheatsheet
When solving algorithm problems or optimizing performance, keep this table in your head.
| Method | Task | Cost (Time Complexity) | Description |
| push | Add to end | O(1) (Fast) | Does not touch existing indices |
| pop | Delete from end | O(1) (Fast) | Does not touch existing indices |
| shift | Delete from front | O(N) (Slow) | Moves all elements forward by one |
| unshift | Add to front | O(N) (Slow) | Moves all elements backward by one |
| splice | Add/Delete middle | O(N) (Slow) | Moves elements after the changed position |
| sort | Sort | O(N log N) | Slowest (High cost) |
| filter/map | Iterate | O(N) | Scans the whole array once |
| arr[i] | Get value | O(1) (Fast) | Direct access via index |
5. Conclusion: What Should I Use?
The reason Chris's Queue code was slow was that he ignored the characteristics of the data structure and overused the expensive shift.
(When dealing with a lot of data, you should implement a Linked List yourself or use a method that avoids shift.)
"Short code does not mean fast code."
Even when writing a single line of function, a developer must be able to imagine how many operations that function will perform internally.
There is a way to express "how many operations" mathematically and elegantly. It is the lingua franca of developers, Big-O Notation.
In the next post, let's find out exactly what symbols like O(1) and O(N) mean.
Continuing in: "[Algorithm] Big-O Notation and Time Complexity: The Performance Report Card of Algorithms."