JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeTopicsjavascriptObjects & Copying
PrevNext
javascript
intermediate
12 min read

Objects & Copying

cloning
deep-copy
freeze
immutability
objects
reference-types
spread-operator
structuredClone

Objects are reference types — assigning or passing them shares the same memory reference. Shallow copies duplicate top-level properties while deep copies (structuredClone) create fully independent clones at all nesting levels.

Key Points

1Reference Semantics

Objects are stored by reference — assigning or passing an object shares the same memory location, so mutations affect all references.

2Shallow Copy

Spread operator, Object.assign, and array methods (slice, from) copy top-level properties but nested objects still share references.

3Deep Copy with structuredClone

Built-in ES2022 method that creates fully independent clones, handling circular refs, Date, Map, and Set — but cannot clone functions or DOM nodes.

4Object.freeze vs Object.seal

freeze() prevents all property changes; seal() prevents add/remove but allows modification. Both are shallow — nested objects remain mutable.

5Equality by Reference

=== compares object references, not content. Two objects with identical properties are not equal unless they point to the same memory location.

What You'll Learn

  • Explain the difference between shallow copy and deep copy and when to use each
  • Use structuredClone and understand its limitations compared to JSON serialization
  • Know the difference between Object.freeze and Object.seal

Deep Dive

Objects and arrays in JavaScript are reference types — variables hold a reference (pointer) to the object in memory, not the object itself. When you assign an object to another variable or pass it to a function, both variables point to the same object. Mutating one affects the other. Understanding this behavior and how to create independent copies is a fundamental interview topic.

Shallow Copy

A shallow copy creates a new object and copies the top-level properties. Primitive values (strings, numbers, booleans) are duplicated, but nested objects and arrays still share the same references as the original. Modifying a nested property in the copy will also modify the original.

Shallow copy methods:

  • Spread operator: { ...obj } for objects, [ ...arr ] for arrays
  • Object.assign({}, obj) — copies enumerable own properties from source to target
  • Array.from(arr), arr.slice(), arr.concat() — all produce shallow copies of arrays

Deep Copy

A deep copy creates a completely independent clone at all nesting levels. No references are shared between the original and the copy.

structuredClone(value) (ES2022) is the modern built-in solution. It handles circular references, Date, Map, Set, ArrayBuffer, RegExp, and typed arrays correctly. Limitations: it cannot clone functions, DOM nodes, Error objects, or property descriptors (getters/setters are evaluated and the result value is copied). Throws a DataCloneError for non-cloneable types.

JSON.parse(JSON.stringify(obj)) is the legacy workaround. It works for plain data objects but has significant data loss: functions are silently dropped, undefined values are stripped, Date objects become ISO strings, NaN and Infinity become null, Map/Set become empty objects, and circular references throw a TypeError. Use structuredClone instead whenever possible.

Object.freeze and Object.seal

These methods control mutability but do not create copies:

  • Object.freeze(obj) — prevents adding, removing, and modifying properties. In strict mode, mutation attempts throw TypeError; in non-strict mode, they silently fail. Critically, freeze is shallow — nested objects remain fully mutable. To deep-freeze, you must recursively freeze all nested objects.
  • Object.seal(obj) — prevents adding and removing properties but allows modifying existing property values. Useful when you want to protect the object's structure while allowing value updates.
  • Object.isFrozen() and Object.isSealed() check the current state.

Property Descriptors

Every object property has a descriptor with value, writable, enumerable, and configurable flags. Object.defineProperty() creates properties with fine-grained control. Object.getOwnPropertyDescriptors() is useful for copying properties with their full descriptors (not just values), which Object.assign does not preserve.

Comparing Objects

=== compares references, not content — two objects with identical properties are not equal unless they are the same object in memory. For deep equality comparison, use a library function or write a recursive comparison. JSON.stringify comparison works for simple objects but fails on key order differences and non-serializable values.

Key Interview Distinction

Shallow copy: new container, shared nested references. Deep copy: fully independent at all levels. structuredClone is the modern standard for deep cloning. Object.freeze prevents mutation but is shallow. Always consider whether your code needs a copy or just a reference — unnecessary deep copies waste memory and CPU.

Fun Fact

The JSON.parse(JSON.stringify()) deep clone trick has been used since 2009, but it took 13 years for JavaScript to get a proper built-in alternative — structuredClone was standardized in 2022, based on an algorithm that web browsers had been using internally since 2010 for postMessage() and IndexedDB.

Continue Learning

Data Structures

intermediate

Destructuring

beginner

Practice What You Learned

What is the difference between shallow copy and deep copy in JavaScript, and how do you create each?
mid
objects
A shallow copy duplicates only top-level properties while nested objects share references; a deep copy recursively duplicates all nested objects creating fully independent copies.
How would you implement JSON.stringify from scratch?
senior
json
A JSON.stringify polyfill recursively converts JavaScript values to JSON strings by handling each type differently: strings get quoted, numbers and booleans become literals, arrays and objects are recursively stringified, and special values like undefined, functions, and Symbols are either omitted or converted to null.
Previous
Modules
Next
Operators
PrevNext