Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
Labs

Beyond the Surface: Mastering Reference Types and the Art of the Deep Copy

JavaScript objects are reference types, and misunderstanding this distinction is the source of some of the most elusive bugs in modern applications. In this lab, you'll investigate how primitives and objects are stored differently in memory, explore why a shallow copy is not always a real copy, and master techniques for safely duplicating nested data structures. You'll leave with a precise mental model for reasoning about object identity and mutation across your JavaScript codebase.

Lab platform
Lab Info
Level
Intermediate
Last updated
Jun 17, 2026
Duration
30m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Step 1: Primitives vs. reference Types

    Copying an object in JavaScript is one of those operations that looks trivial but hides genuine complexity. In this lab, you'll work with a configuration manager, a small application that stores and retrieves developer tool settings as nested JavaScript objects. You'll implement four distinct copying strategies, from the spread operator to structuredClone, explore how methods stored as object properties interact with this, and fix a reference bug that silently exposes the manager's internal state to callers.

    The starter code provides the config object, four placeholder copy functions, and a ConfigManager class with the reference bug already in place. This first step builds the mental model you'll need before writing any code: you'll trace the difference between primitive values stored on the stack and objects stored on the heap, and see why assigning one object variable to another copies only the pointer, not the data.

    Concepts covered in this step:

    • Primitive types (number, string, boolean, null, undefined) are stored by value on the stack; reassigning one variable does not affect another.
    • Objects are stored by reference on the heap; assigning an object to a new variable copies the pointer, not the data.
    • Two variables holding the same reference will both reflect any mutation made through either one.
    • This shared-reference behavior is the root cause of the config manager bug that the lab resolves.

    info> This lab experience was developed by the Pluralsight team using an internally developed AI tool. All sections were verified by human experts for accuracy prior to publications. However, content may still contain errors or inaccuracies, and we recommend independent verification. To report a problem or provide feedback, click here. Feedback may be used to improve accuracy in accordance with our Privacy Policy.

    To report a problem or provide feedback, click here. Feedback may be used to improve accuracy in accordance with our Privacy Policy.

  2. Challenge

    Step 2: Shallow copying explored

    The spread operator and Object.assign are the tools developers most commonly reach for when copying an object. Both produce what is known as a shallow copy, and both behave identically for flat objects with a single level of nesting. The lab's codebase lives in the application directory; you'll open src/configManager.js and implement each approach in the placeholder functions already waiting there. By the end of this step, you'll have concrete evidence of exactly where shallow copying breaks down when the object contains nested properties.

  3. Challenge

    Step 3: Deep copying strategies

    Shallow copies create a new top-level object but leave nested objects pointing to the same location in memory, which means mutations to a copy's nested properties change the original as well. Two deep copy strategies solve that problem: JSON.stringify/JSON.parse for the common case, and structuredClone for objects that contain values JSON cannot represent, such as Date instances. You'll implement both in src/configManager.js, then run a demo script that prints all four copy strategies side by side, showing exactly when each approach is the right choice.

  4. Challenge

    Step 4: Functions as properties and reference semantics

    With reliable deep copy functions now implemented, this step turns to one more dimension of reference semantics: functions stored as object properties. You'll add a describe method directly to the config object literal, then call it on both the original and a shallow copy to see how this resolves at the call site rather than where the method was defined. The step closes with the core fix: you'll update ConfigManager.getConfig() to return a deep copy instead of the raw internal reference, eliminating the bug present in the starter code. After this fix, the config manager will be fully protected against external mutation at any depth. You can confirm your changes made an impact by again running:

    node src/demo.js
    

    You should see the final block of the output has changed to reflect that the copies are now safe:

    === ConfigManager: safe copy ===
    Internal theme after mutation attempt: dark
    [SAFE] getConfig() returns a deep copy - internal state is protected
    
  5. Challenge

    Lab complete

    You've completed the lab and built a fully reference-safe configuration manager. You traced how primitive values and objects are stored differently in memory, implemented shallow copies with the spread operator and Object.assign, and mastered two deep copy strategies, JSON.stringify/JSON.parse and structuredClone, suited to different data shapes. You added a describe method that demonstrates how this resolves at the call site, and fixed ConfigManager.getConfig() to return an independent snapshot instead of a live reference, protecting the manager's internal state from external mutation at any depth.

About the author

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight