DEV Community

김영민
김영민

Posted on

Understanding JavaScript Copy by Reference

JavaScript Copy by Reference

JavaScript is a versatile language with various data types, including primitive and reference types. Understanding how these types are copied is crucial for effective programming. In this article, we'll delve into the world of JavaScript copy by reference, exploring the differences between primitive and reference types, shallow and deep copying, and providing practical tips for working with these concepts.

Primitive Types

Primitive types in JavaScript are values stored directly in variables. When you copy a primitive value, it creates a new copy of the value in a new memory space.

  • Examples: string, number, boolean, undefined, null, symbol, bigint
let a = 10;
let b = a;  // a's value is copied to b

b = 20;  // only b is changed

console.log(a);  // 10
console.log(b);  // 20
Enter fullscreen mode Exit fullscreen mode
  • Here, a and b have independent values.
  • Although a's value is copied to b, they occupy different memory spaces. Therefore, changing b doesn't affect a.

Reference Types

Reference types in JavaScript store the reference address of an object in variables. When you copy an object or array, you're copying the reference address, not the value. This means both variables will point to the same object.

  • Examples: object, array, function, date, regExp, map, set
let person1 = {
  name: 'John',
  age: 30
};

let person2 = person1;  // person1's reference address is copied to person2

person2.age = 35;  // person2's age value is changed

console.log(person1.age);  // 35 (person1 is also changed)
console.log(person2.age);  // 35
Enter fullscreen mode Exit fullscreen mode
  • person1 and person2 point to the same object. Changing person2 affects person1 because they reference the same memory space.

Characteristics of Copy by Reference

  • Both variables point to the same object, so changing one affects the other.
  • No new object is created when copying arrays or objects; only the reference address is copied.

Shallow Copy

When copying reference types, we use the concept of shallow copying. Shallow copying only copies the top-level properties of an object and copies the reference to inner objects or arrays.

Shallow Copy Example

let original = {
  name: 'Alice',
  hobbies: ['reading', 'biking']
};

let copy = { ...original };  // shallow copy using spread operator

copy.name = 'Bob';  // only the copy is changed
copy.hobbies.push('swimming');  // both the original and copy are changed

console.log(original.name);    // Alice (unchanged)
console.log(original.hobbies); // ['reading', 'biking', 'swimming']
console.log(copy.hobbies);     // ['reading', 'biking', 'swimming']
Enter fullscreen mode Exit fullscreen mode
  • Changing name only affects the copy, but both the original and copy share the same hobbies array.

Deep Copy

Deep copying creates a completely independent object by copying all nested objects and arrays. This solves the reference problem that can occur with shallow copying.

Deep Copy Example

  • Using JSON.parse() and JSON.stringify() for deep copying
let original = {
  name: 'Alice',
  hobbies: ['reading', 'biking']
};

let copy = JSON.parse(JSON.stringify(original));  // deep copy

copy.name = 'Bob';  // only the copy is changed
copy.hobbies.push('swimming');  // only the copy is changed

console.log(original.name);    // Alice (unchanged)
console.log(original.hobbies); // ['reading', 'biking']
console.log(copy.hobbies);     // ['reading', 'biking', 'swimming']
Enter fullscreen mode Exit fullscreen mode
  • JSON.parse(JSON.stringify()) creates a new copy of the object, including all nested objects and arrays, solving the reference issue.

Alternative Methods

  • Using the cloneDeep() function from the lodash library for deep copying
const _ = require('lodash');
let copy = _.cloneDeep(original);
Enter fullscreen mode Exit fullscreen mode
  • This method is particularly useful when dealing with complex, nested objects.

In conclusion, understanding how JavaScript copies values, whether by reference or by value, is essential for writing effective and bug-free code. By recognizing the differences between primitive and reference types and knowing when to use shallow or deep copying, you can better manage your data and avoid common pitfalls. Remember, the key to mastering JavaScript is practice and a deep understanding of its fundamental concepts.

Top comments (0)