FrontendAtlas
Interview Questions
Home>JavaScript interview questions> JavaScript coding challenges >Implement shallowClone() in JavaScript

Implement shallowClone() in JavaScript

easy
By FrontendAtlas Editorial · Updated Jul 14, 2026
Implement shallowClone(value) in JavaScript. Your function should accept an object or array and return a new top-level container while preserving nested object and array references. Array holes, length, custom own enumerable string properties, and own enumerable symbol properties are part of the contract. Primitives, null, and unsupported root values should throw TypeError. This challenge includes starter code, tests, examples for object and array cloning, shallow vs deep clone edge cases, and interview follow-ups around Object.assign(), spread syntax, prototypes, descriptors, and structuredClone().

Expected behavior

Your shallowClone(value) implementation should:

  • Accept only objects and arrays as root inputs.
  • Arrays return a new array reference with the same length, holes, top-level items, and custom own enumerable properties.
  • Objects return a new object reference with the same own enumerable properties.
  • Top-level primitive property and item values are copied by value inside the cloned container.
  • Nested objects and arrays remain shared references.
  • Updating a top-level property or array slot on the clone does not mutate the original container.
  • Mutating a nested object or nested array through the clone is visible through the original.
  • null and primitive root inputs throw TypeError.
  • The base solution copies own enumerable string and symbol properties.
  • Prototype chains and property descriptors are not preserved.

Arguments

  • value: Object | Array — The object or array to clone.

Returns

Object | Array — A new shallow-cloned object or array.
Examples
// Array shallow clone
const original = [1, { count: 2 }];
const copy = shallowClone(original);

copy === original; // false
copy[1] === original[1]; // true

copy[0] = 99;
original[0]; // 1

copy[1].count = 3;
original[1].count; // 3

// Object shallow clone
const user = { name: 'Ada', meta: { active: true } };
const cloned = shallowClone(user);

cloned === user; // false
cloned.meta === user.meta; // true

Solution

Overview

Interview answer: the base prompt is to create a new top-level container while preserving nested references. Guard null and primitive values first. For arrays, allocate new Array(value.length) and copy with Object.assign so holes and length survive while custom own enumerable string and symbol properties are included. For objects, use Object.assign({}, value). Both branches ignore inherited prototype properties. Deep cloning, structuredClone(), JSON cloning, prototypes, descriptors, Maps, Sets, Dates, and circular references are follow-ups, not part of the minimal shallowClone(value) contract.

Shallow clone vs deep clone: A shallow clone creates a new top-level object or array but keeps nested references shared. A deep clone recursively creates new nested objects and arrays. This challenge is intentionally shallow; deep clone behavior belongs in the related deep clone challenge.

1

Approach: Branch on array vs object

Guard unsupported root values before cloning: null and primitives should throw a TypeError. For an array, allocate new Array(value.length) so trailing holes and length are retained, then use Object.assign to copy its present indexes plus custom own enumerable string and symbol properties. Otherwise clone the object with Object.assign({}, value). Object.assign ignores inherited prototype properties, runs in O(n) time over own enumerable properties, uses O(n) space for the new top-level container, and preserves nested references by design.

export default function shallowClone(value) {
  if (value === null || typeof value !== 'object') {
    throw new TypeError('Expected object or array');
  }

  if (Array.isArray(value)) {
    return Object.assign(new Array(value.length), value);
  }

  return Object.assign({}, value);
}
export default function shallowClone<T extends Record<string, any> | any[]>(value: T): T {
  if (value === null || typeof value !== 'object') {
    throw new TypeError('Expected object or array');
  }

  if (Array.isArray(value)) {
    return Object.assign(new Array(value.length), value) as T;
  }

  return Object.assign({}, value) as T;
}

Notes & Pitfalls

Pitfalls
  • This is a shallow clone: nested objects and arrays are still shared by reference.
  • `null` is an object in JS, so guard `value === null` before the object branch.
  • `Object.assign` copies own enumerable string and symbol properties, but it does not preserve descriptors or prototypes.
  • Avoid `for...in` for the base solution because it can walk inherited prototype properties.
Edge cases
  • `[]` returns a new empty array (different reference).
  • `{}` returns a new empty object (different reference).
  • Nested objects remain the same reference in the clone.
  • Sparse arrays keep their holes, length, and custom enumerable string and symbol properties.
Techniques
  • Array copying with `Object.assign(new Array(value.length), value)`.
  • Object copying with `Object.assign({}, value)`.
  • Guard-first input validation before branching.

Common interview follow-ups:

  • How would structuredClone() change the behavior for nested references?
  • When would you preserve prototypes or descriptors?
  • How would Maps, Sets, Dates, class instances, or circular references change the contract?
  • When is Object.assign({}, value) preferable to object spread, or vice versa?

Resources

  • MDN – Object.assign()
  • MDN – Array constructor

Related links

JavaScript deep clone coding challengeCodingshallow vs deep clone interview answerJavaScriptimmutable array update challengeCodingJavaScript object references interview questionJavaScriptJavaScript coding interview questionsGuide

Guides

Frontend interview preparation guideGuideFrontend coding interview questions and prep guideBlueprintJavaScript Problems That Actually Show UpBlueprintBuild Great UI in 60 MinutesBlueprint

Preparing for interviews? Use Frontend Coding Challenges first, then move into a concrete Study Plan before targeted Company Prep.

Open frontend interview questionsBrowse JavaScript interview questionsOpen Essential 60Open Machine Coding HubOpen Frontend Coding ChallengesOpen System DesignOpen Interview Prep GuideOpen System Design BlueprintOpen Framework Prep PathsOpen Study PlansOpen JavaScript mastery study planOpen Company PrepOpen JavaScript Framework Prep Guide
↗Incidents hub
← Prev←29 / 88Next →→