DEV Community

Cover image for Understanding Memory Location in JavaScript
Mariana Caldas for Web Dev Path

Posted on

Understanding Memory Location in JavaScript

JavaScript powers the web with its ability to build interactive websites and applications. Despite its simplicity, certain aspects, like "memory location," can be complex. This article explores memory location in JavaScript, its significance, and its impact on coding, using practical examples for clarity.


What is memory location?

Memory location, in the context of programming, refers to the place in a computer's memory where data is stored. Think of it as a unique address for a specific piece of information in your computer's memory. In JavaScript, when you work with variables and objects, you're essentially dealing with memory locations.


Why does JavaScript use memory location?

JavaScript, like many programming languages, uses memory locations for a few important reasons:

Efficiency: Memory locations make data access and manipulation efficient. When you work with variables and objects, you're referencing the memory location of the data, not the data itself. This allows JavaScript to quickly access and update the data when needed.

Passing by Reference: This is a bit like sharing the address of a house rather than the house itself. When JavaScript functions need to work with objects, they use the object's memory address. This means they can all work on the same object without needing to make and pass around copies of it, saving time and space.

Immutability: In JavaScript, simple things like numbers and text (we call these 'primitive data types') are copied when you move them around. However, objects (which are like collections of different pieces of data) are treated differently. They are passed by their memory address. So, you can change what's inside an object (like painting the walls of a house), but the basic address of the object doesn't change.


Modifying object properties without changing the object itself

When you change the properties of an object in JavaScript, it's like doing home improvements without changing the home's address. This is really useful because:

  • It's easier and faster to just update what you already have rather than building something new from scratch.
  • Everyone who knows the original address (or in JavaScript terms, references the object) can still find it and see the new changes.
  • You can make sure that changes to your object happen in a controlled way, just like planning out home renovations.

Example:

const spaceship = {
  homePlanet: 'Earth',
  color: 'dream blue'
};

function upgradeSpaceship(obj) {
  obj.color = 'glorious gold';
  obj.hasHyperdrive = true;
}

upgradeSpaceship(spaceship);

console.log(spaceship);
// Output:
// {
//   homePlanet: 'Earth',
//   color: 'glorious gold',
//   hasHyperdrive: true
// }
Enter fullscreen mode Exit fullscreen mode

In this example, the object spaceship creates a new memory location. The upgradeSpaceship function adds new functionality (hasHyperdrive) to the spaceship and changes its appearance (color). This is useful because the spaceship object may be used in many places in the code, and all references to it now automatically have access to the updated properties.


Reassigning the object will not work

Now, let's look at what wouldn't work in this context:

Attempting to reassign the object entirely within a function does not change the original object outside the function. This is because the reassignment creates a new memory location for the object inside the function, which does not affect the original object's memory location.

Example:

const spaceship = {
  homePlanet: 'Earth',
  color: 'silver'
};

function replaceSpaceship(obj) {
  obj = {
    homePlanet: 'Mars',
    color: 'red',
    hasHyperdrive: true
  };
  return obj;
}

replaceSpaceship(spaceship);
console.log(spaceship);

// Output of the first console.log inside replaceSpaceship:
// {
//   homePlanet: 'Mars',
//   color: 'red',
//   hasHyperdrive: true
// }
// Output of the second console.log:
// {
//   homePlanet: 'Earth',
//   color: 'silver'
// }
Enter fullscreen mode Exit fullscreen mode

In the replaceSpaceship function, we attempted to give obj a new value. Inside the function, obj points to a new object with a 'Mars' homePlanet. However, outside the function, spaceship still points to the original object with an 'Earth' homePlanet. This is because the obj parameter inside replaceSpaceship is a local variable to the function and reassigning it does not affect the original spaceship variable.


Additional considerations

Garbage collection

This process is directly related to how JavaScript manages memory locations. When data is no longer needed, JavaScript clears its memory location, making space for new data.

Think of garbage collection like a cleaning crew in a hotel. When guests (data) check out (are no longer needed), the crew cleans up the room (frees up memory) for new guests. So, when a function finishes running, JavaScript's garbage collection automatically cleans up variables that were only used inside that function, preventing memory waste.

Deep vs shallow copy

This concept is all about how memory locations are handled during copying. A shallow copy means multiple references to the same memory location, while a deep copy creates a new memory location for the copied data.

Imagine you have a shopping list on your phone. A shallow copy is like sharing the list with a friend through a shared app. If you change the list, your friend sees those changes too. A deep copy is like sending a text message with your list – even if you change your original list later, the text message stays the same.

Example:

let originalList = { items: ['apple', 'banana'] };
let shallowCopy = originalList; // Changes to originalList will affect shallowCopy
let deepCopy = JSON.parse(JSON.stringify(originalList)); // deepCopy remains independent
Enter fullscreen mode Exit fullscreen mode

Scope and closure

These concepts are fundamentally about how JavaScript's memory locations are accessed. Scope determines which memory locations are accessible from a given part of the code, and closures allow functions to remember and access memory locations (variables) from their scope even after that scope has closed.

Think of scope as a private diary. Only you (the function where the variable is declared) can read it. A closure is like a photocopy of a page from your diary that you give to a friend – they can read that page even if the diary is locked away.

Example:

function outerFunction() {
  let secretMessage = 'I love JavaScript';
  function innerFunction() {
    console.log(secretMessage); // innerFunction can access secretMessage
  }
  return innerFunction;
}
let myClosure = outerFunction();
myClosure(); // Outputs: 'I love JavaScript'
Enter fullscreen mode Exit fullscreen mode

Conclusion

Understanding memory location is crucial in JavaScript for efficient and bug-free coding. It underpins data handling, allowing for effective object manipulation while maintaining original references. As you delve deeper into JavaScript, this concept becomes integral to developing complex and robust applications. Remember, managing objects in JavaScript is a bit like managing a house: you can change the interior as much as you like, but the address stays the same.

Top comments (0)