A Simple Guide to Heaps, Stacks, References and Values in Javascript

Johnny Simpson - Mar 28 '22 - - Dev Community

A common concept in software engineering in general is the idea of reference versus value. Javascript has an interesting way of storing variables, objects, and functions, and misunderstanding this can lead to confusion further down the road. It's important developers to know how these concepts work, since it is fundamental to Javascript. In this article we'll cover a how Javascript manages values and references, which will pay dividends when working on complicated applications and websites.

Memory Storage in Javascript

To understand what we mean when we say Javascript stores values and reference, we need to understand where Javascript stores them. There are two places Javascript stores this data:

  • The stack, which is a scratch space for the current Javascript thread. Since Javascript is usually only single threaded, there is usually one stack. The stack is also limited in size, which is why numbers in Javascript can only be so big.
  • The heap, which is a dynamic memory store at an application level. Accessing and retrieving data from the heap is a little more complicated, but the data store is dynamic - meaning it will expand if it needs to, and not limited.

When something is stored in the stack, it is stored by value. When something is stored in the heap, it is stored by reference.

Stack Storage

Javascript stores regular primitive types, like number, string, boolean, null, undefined and bigint in the stack. As you define variables in your code, they are added to the top of the stack:

let myVar = 15;
let myName = 'Johnny';
let someOtherVar = false;
let check = null;
Enter fullscreen mode Exit fullscreen mode

Stack:
An example of the stack in Javascript

This means if we redefine a variable in Javascript, it becomes an entirely new value. For example:

let myNumber = 5;
let newNumber = myNumber;

++newNumber;

// Returns 5, 6
console.log(myNumber, newNumber);
Enter fullscreen mode Exit fullscreen mode

Stack:
An example of the Stack in Javascript

Since Javascript creates a new value for anything stored in the stack, even though we referred to newNumber being the same as myNumber, they do not refer to the same thing. These two variables become independent of each other, and as such altering one will not alter the other.

Heap Storage

If you are defining something which is not a primitive type, and is instead an object, it is stored in the heap. In Javascript, functions, and arrays also fall into the "object" category.

Instead of being easily accessible in the stack, heap definitions need to be defined with a little bit more thought. Everything stored in the heap is instead given a reference.

Example

Let's say we define both an object and a function in Javascript:

let myObject = { name: "Hello" };
let myFunction = function() {
    return "Hello World";
}
Enter fullscreen mode Exit fullscreen mode

As shown below, a new reference is made for each myObject and myFunction, with references #000 and #001 respectively. That reference is the place in memory where they are stored.

Heap Storage
An example of heap storage in Javascript

The main difference with heap storage when compared to the stack, is that if we reference an object again, the reference remains the same. That means if we try to create a new version of myObject, it will instead keep the same reference:

let myObject = { name: "Hello" };
let newObject = myObject;
newObject.name = "Goodbye";

// Returns { name: "Goodbye" }, { name: "Goodbye" }
console.log(myObject, newObject);
Enter fullscreen mode Exit fullscreen mode

When we change one, both change - which is the opposite of when we stored data in the stack.

Heap Storage
An example of heap storage in Javascript

Equivalence in Value and References

Since Javascript stores the definition of objects as a reference, it can be a little confusing. For values, we can easily compare if two things are equal:

let a = 5;
let b = 5;

// Returns true
console.log(a === b);
Enter fullscreen mode Exit fullscreen mode

We can easily compare these two, because they are both values. For references, though, it's a different story. Comparing two objects, compares them by reference. Even if their value is the same, they are not equal as their references are different:

let a = { name: "Hello" };
let b = { name: "Hello" };

// Returns false
console.log(a === b);
Enter fullscreen mode Exit fullscreen mode

Conclusion

References and values have real implications for your code - especially when making comparisons, understanding the difference is critical. Not only that, but the stack is much less expensive performance wise than the heap, and it's very easy to make too many stack entries if you aren't aware of how it works.

If you know how Javascript handles heap and stack storage, you can start to optimize your application's performance to work best within these rules. I hope you've enjoyed this quick guide on how references and values work in Javascript. If you want more Javascript content, it can be found here.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .