- Lab
-
Libraries: If you want this lab, consider one of these libraries.
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 Info
Table of Contents
-
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 withthis, and fix a reference bug that silently exposes the manager's internal state to callers.The starter code provides the
configobject, four placeholder copy functions, and aConfigManagerclass 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. -
Challenge
Step 2: Shallow copying explored
The spread operator and
Object.assignare 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 theapplicationdirectory; you'll opensrc/configManager.jsand 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. -
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.parsefor the common case, andstructuredClonefor objects that contain values JSON cannot represent, such asDateinstances. You'll implement both insrc/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. -
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
describemethod directly to theconfigobject literal, then call it on both the original and a shallow copy to see howthisresolves at the call site rather than where the method was defined. The step closes with the core fix: you'll updateConfigManager.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.jsYou 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 -
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.parseandstructuredClone, suited to different data shapes. You added adescribemethod that demonstrates howthisresolves at the call site, and fixedConfigManager.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.