A stack is a data structure that follows the LIFO (Last In, First Out) principle. Think of it like a stack of books 📚: you can only add a new book to the top or remove one from the top.
Operations performed on a Stack
- peek – Returns the value at the top of the stack without removing it
- isEmpty – Checks if the stack is empty
- length – Gets the number of elements in the stack
- push – Adds a new value to the top of the stack
- pop – Removes and returns the value at the top of the stack
JavaScript Code for a Stack
I have implemented the JavaScript code for a stack data structure using classes. But why classes? Why not use an array, which is simple, as arrays in JS have inbuilt methods like push and pop? While arrays would work, they can sometimes require resizing, which can be an O(n) operation, the stack implementation guarantees O(1) performance for push and pop operations. Additionally, in interview settings, you might be asked to create a stack without relying on built-in array methods.
Note: Each node stores its own data and a pointer (or reference) to the next node location (memory address).
class Node {
constructor(value) {
this.value = value; // Data stored in the node
this.next = null; // Pointer to the next node
}
}
class Stack {
constructor() {
this.head = null;
this.size = 0;
}
// Returns the value of the head node
peek() {
return this.head?.value;
}
// Checks if the list is empty
isEmpty() {
return this.size === 0;
}
// Returns the length of the stack
get length() {
return this.size;
}
// Adds a new node with the given value to the top of the stack
push(value) {
const newNode = new Node(value);
if (this.isEmpty()) {
this.head = newNode;
} else {
newNode.next = this.head;
this.head = newNode;
}
return ++this.size;
}
// Removes the first node from the stack and returns it's value
pop() {
if (this.isEmpty()) {
return undefined;
}
const temp = this.head;
this.head = this.head.next;
this.size--;
return temp.value;
}
}
const myStack = new Stack();
myStack.push("value 1");
myStack.push("value 2");
myStack.push("value 3");
console.log(myStack.head);
/*
Node {
value: 'value 3',
next: Node {
value: 'value 2',
next: Node { value: 'value 1', next: null }
}
}
*/
console.log(myStack.size); // 3
console.log(myStack.peek()); // value 3
console.log(myStack.pop()); // value 3
console.log(myStack.pop()); // value 2
console.log(myStack.pop()); // value 1
console.log(myStack.pop()); // undefined
Time Complexity – O(1)
All the operations (push, pop, peek, isEmpty, and length) take constant time O(1).
Real-world Applications of a Stack
- Navigation systems in browser and various apps
- Undo and Redo functionality in text editors, image editing software
- Function Call Stack – keep track of the order in which functions are called, memory management
Data Structures in JavaScript Series
- Implementing Stack in JavaScript
- Implementing Queue in JavaScript
- Singly Linked List in JavaScript
- Doubly Linked List in JavaScript