Playing with data structures in Javascript — Stack

Anish K.
CloudBoost
Published in
4 min readDec 9, 2017

--

Follow https://stackfull.dev/ for more of such articles.

Javascript is evolving each day. With the rapid growth of frameworks and platforms like React, Angular, Vue, NodeJS, Electron, React Native, it has become quite common to use javascript for large-scale applications. Gone are those days when Javascript was confined to ‘a bit of jquery here and a bit there’ . It also means that now it’s important to understand what’s the right tool for a specific problem, to write efficient and performant applications in javascript.

Data structures are quite important in this context. Being a self-taught programmer, I never really studied data structures in graduation. But lately I have been working on large-scale applications based on javascript, and that taught me about the importance of using right tools in the right situation ( ‘tools’ here don’t refer to data structures only, there are a couple of other things as well which I would be covering in further blog posts). Some simple changes at the ground level can boost the performance of your application by a great margin.

In this first blog post, I would be starting with a basic data structure — Stack.

Stacks

Stacks are simple to understand. if you look at the image above, you can understand most of the properties of the stack. The first item in the above-shown stack is the ‘red’ portion (with ‘out’ written upon it). But it would be the last item to be removed, since we must remove the other items, stacked above it, before pulling it out. To put it simply, the first item in the stack is the last item that gets removed.

Let’s jump into some code to see the exact implementation and hopefully that would make things a lot clearer. I would be using ES6 syntax to keep things cleaner and easier to grasp.

Here’s how our stack should look like :

class Stack {
constructor(){

}

push(item){
//push item to the stack
}

pop(){
//pull out the topmost item (last item) from stack
}

peek(){
// see what's the last item in stack
}

size(){
//no. of items in stack
}

isEmpty(){
// return whether the stack is empty or not
}
}

Let’s start binding the pieces together. We can use an array under the hood, to store the items of the stack, like so :

class Stack {
constructor(){
this._items = [];
}
...

_(underscore) before a variable name has been used to convey that this variable is supposed to be used internally only, and any instances of Stack shouldn’t ever access it anyhow.

Let’s implement the other missing pieces of our stack:

class Stack {
constructor(){
this._items = []
}

push(item){
//push item to the stack
return this._items.push(item)
}

pop(){
//pull out the topmost item (last item) from stack
return this._items.pop()
}

peek(){
// see what's the last item in stack
return this._items[this._items.length-1]
}

size(){
//no. of items in stack
return this._items.length
}

isEmpty(){
// return whether the stack is empty or not
return this._items.length==0
}
}

We have got the basic structure for the stack ready. But there are still a few features we would want to implement:

  1. Upon initialization, we can pass some items to the stack
  2. We should be able to stack and unstack multiple items at once
class Stack {
constructor(...items){
this._items = []

if(items.length>0)
items.forEach(item => this._items.push(item) )

}

push(...items){
//push item to the stack
items.forEach(item => this._items.push(item) )
return this._items;

}

pop(count=0){
//pull out the topmost item (last item) from stack
if(count===0)
return this._items.pop()
else
return this._items.splice( -count, count )
}

peek(){
// see what's the last item in stack
return this._items[this._items.length-1]
}

size(){
//no. of items in stack
return this._items.length
}

isEmpty(){
// return whether the stack is empty or not
return this._items.length==0
}

toArray(){
return _items;
}
}

Now our stack implementation looks quite better. But we still have to solve some issues:

  1. Anyone can still access our _items variable and change it externally. We can use WeakMap in ES6 to solve this issue
  2. Our Stack needs to be namespaced properly to avoid polluting the global namespace. For this, we will wrap our whole implementation in a closure.
  3. We need a way to see the current items in our stack. For this we will be adding a toArray() method

Here’s the final implementation, with these issues resolved :

let Stack = (()=>{

let map = new WeakMap();
let _items = [];
class Stack {
constructor(...items){
// let's store our items array inside the weakmap
map.set(this, []);
// let's get the items array from map, and store it in _items for easy access elsewhere
_items = map.get(this);

//if constructor receives any items, it should be stacked up
this.push(..items)

}

push(...items){
//push item to the stack
items.forEach(item => _items.push(item) )
return _items;

}

pop(count=1){
//pull out the topmost item (last item) from stack
return _items.splice( -count, count )
}

peek(){
// see what's the last item in stack
return _items[_items.length-1]
}

size(){
//no. of items in stack
return _items.length
}

isEmpty(){
// return whether the stack is empty or not
return _items.length==0
}

toArray(){
return _items;
}
}
return Stack;
})();

I have saved the final implementation as a public gist:
https://gist.github.com/anish000kumar/0fd37acc866a9577cf259980500b1bbe

Usage of Stack

Here’s a small snippet, illustrating how can we use this stack :

let my_stack = new Stack(1,24,4);
// [1, 24, 4]
my_stack.push(23)
//[1, 24, 4, 23]
my_stack.push(1,2,342);
//[1, 24, 4, 23, 1, 2, 342]
my_stack.pop();
//[1, 24, 4, 23, 1, 2]
my_stack.pop(3)
//[1, 24, 4]
my_stack.isEmpty()
// false
my_stack.size();
//3
my_stack.toArray();
//[1, 24, 4]

Feel free to share your thoughts about this article through the comments below.

--

--