JavaScript variables hold different types of data: primitives (Undefined, Null, Boolean, Number, String) and objects (reference types). Primitive values are stored directly in memory, while objects are stored as references.
Primitive vs Reference Types
Primitive values are immutable. When copied, a new independent value is created:
let a = 1;
let b = a;
b = 2;
console.log(a); // 1
Reference types point to memory locations. Copying creates a new reference to the same object:
let obj1 = { value: 1 };
let obj2 = obj1;
obj2.value = 2;
console.log(obj1.value); // 2
Shallow Copy
A shallow copy duplicates top-level properties but nested objects remain shared references.
Object.assign()
Object.assign() performs a shallow copy:
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);
copy.a = 3; // Doesn't affect original
copy.b.c = 4; // Affects original
console.log(original); // { a: 1, b: { c: 4 } }
Spread Operator
The spread syntax also creates shallow copies:
const copy = { ...original };
Array Methods
For arrays, use slice() or concat():
const arr = [1, 2, { d: 3 }];
const arrCopy = arr.slice();
arrCopy[0] = 10; // Doesn't affect original
arrCopy[2].d = 30; // Affects original
Deep Copy
A deep copy creates completely independant copies of all nested elements.
JSON Methods
JSON.parse(JSON.stringify()) creates a deep copy but has limitations:
- Loses
undefinedand function properties - Doesn't copy prototype chain
- Fails with circular references
const obj = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 20;
console.log(obj.b.c); // 2
Recursive Function
Implement a deep copy function to handle nested objects:
function deepClone(source) {
if (source === null || typeof source !== 'object') {
return source;
}
const target = Array.isArray(source) ? [] : {};
for (const key in source) {
if (source.hasOwnProperty(key)) {
target[key] = deepClone(source[key]);
}
}
return target;
}
const original = { a: 1, b: { c: 2 } };
const cloned = deepClone(original);
cloned.b.c = 20;
console.log(original.b.c); // 2
Libray Solutions
Libraries like Lodash offer _.cloneDeep() for robust deep cloning.