Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

JavaScript Deep Copy Implementation Guide for Interview Assessments

Tech 1

Shallow vs Deep Copy

Shallow copy creates a new object with an exact duplicate of the original object's top-level property values. For primitive type porperties, the actual value is copied, while for reference type properties, only the memory pointer is copied. Modifying nested reference values in the copied object will alter the corresponding value in the original object.

Deep copy generates a full, independent duplicate of the source object from memory, allocating separate heap space for the new copy. Changes made to the deep copied object will have no impact on the original source object.

Common Off-the-Shelf Deep Copy Implementations

JSON Serialization/Deserialization

This approach first converts the source object to a JSON string via JSON.stringify(), then parses the string back into a new JavaScript object with JSON.parse(). The newly created object ocupies separate memory space, achieving deep copy for eligible data.

const sourceObj = {
  username: "Li Ming",
  grades: {
    physics: 98,
    chemistry: 92
  }
};

const copiedObj = JSON.parse(JSON.stringify(sourceObj));
copiedObj.grades.physics = 65;

console.log("Original object: ", sourceObj);
// Output: Original object: { username: 'Li Ming', grades: { physics: 98, chemistry: 92 } }
console.log("Copied object: ", copiedObj);
// Output: Copied object: { username: 'Li Ming', grades: { physics: 65, chemistry: 92 } }

Key limitations of this method:

  • Omits properties with undefined values
  • Fails to serialize function properties
  • Does not correctly copy RegExp instances
  • Throws an error when processing objects with circular references
  • Drops all Symbol-type properties

Lodash cloneDeep Utility

The widely used JavaScript utility library Lodash provides the _.cloneDeep method, a production-ready implementation that supports deep copy for nearly all common JavaScript data types.

import lodash from 'lodash';

const inventory = {
  productId: "P-2024-001",
  stockInfo: {
    warehouseA: 120,
    warehouseB: 87
  }
};

const inventoryCopy = lodash.cloneDeep(inventory);

This implementation covers all edge cases the JSON serialization approach fails to handle, with no common limitations for standard business use cases.

Handwritten Deep Copy Implementations

Basic Recursive Version

This minimal implementation handles plain objects and arrays, meeting the requirements for most basic interview scenarios.

function basicDeepClone(target) {
  // Return primitive values directly
  if (typeof target !== 'object' || target === null) {
    return target;
  }
  // Initialize container matching input type
  const clonedResult = Array.isArray(target) ? [] : {};
  for (const key in target) {
    if (target.hasOwnProperty(key)) {
      clonedResult[key] = basicDeepClone(target[key]);
    }
  }
  return clonedResult;
}

Limitations of the basic version include no support for circular references, special reference types (Date, RegExp, Function), and potential performance bottlenecks for extremely deeply nested objects.

Advanced Edge Case Support Version

This iteration adds handling for common edge cases, including circular references and special built-in object types:

function advancedDeepClone(target, cache = new WeakMap()) {
  // Return primitive type values directly
  if (typeof target !== 'object' || target === null) return target;
  // Handle special built-in reference types
  if (target instanceof Date) return new Date(target);
  if (target instanceof RegExp) return new RegExp(target);
  // Return cached value to avoid infinite loops from circular references
  if (cache.has(target)) return cache.get(target);
  // Initialize new object or array container
  const clonedOutput = Array.isArray(target) ? [] : {};
  cache.set(target, clonedOutput);
  // Recursively copy all own properties
  for (const key in target) {
    if (Object.prototype.hasOwnProperty.call(target, key)) {
      clonedOutput[key] = advancedDeepClone(target[key], cache);
    }
  }
  return clonedOutput;
}

Related Articles

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.