티스토리 뷰

반응형

원시값(Primitive Value)과 참조값(Reference Value), 객체 복사(얕은 복사 Shallow Copy, 깊은 복사 Deep Copy)

 

자바스크립트에서의 데이터는 원시값(Primitive Value)과 참조값(Reference Value) 두가지 유형으로 나눌수 있다.

이 두 유형은 메모리에 저장되는 방식과 복사되는 방식이 다르다.

 

 

원시값(Primitive Value)

  • 종류로는 string, number(Infinity, NaN 포함), boolean, undefined, null, symbol, bigint이 있다.
  • 값 자체를 저장하며, 변수에 할당할 때 새로운 메모리 공간에 저장한다. (때문에 불변하다. = 한번 생성된 값을 변경할 수 없다.)
  • 값을 복사하게되면 새로운 메모리 공간에 할당된다. (독립적인 값)
let a = 10; 
let b = a; // a의 값을 b에 복사 (새로운 메모리 공간 할당) b = 20; 

console.log(a); // 10 (원래 값 유지) 
console.log(b); // 20 (새로운 값)

 

a의 값을 b에 복사할 때 새로운 메모리 공간이 생성되었기 때문에 b의 값을 변경해도 a에 영향을 주지 않는다. 

 

 

 

참조값(Reference Value)

  • 종류로는 Object, Array, Function, Set, Map, WeakSet, WeakMap 이 있다.
  • 메모리 주소(참조)를 저장하는 데이터 타입이며, 변수에는 객체의 메모리 주소(참조값)가 저장된다.
  • 값을 복사하게되면 메모리 주소를 공유(참조)하므로 원복 객체도 영향을 받는다. (얕은 복사)  
let obj1 = { name: "Alice" }; 
let obj2 = obj1; // 같은 메모리 주소를 공유 (얕은 복사) 

obj2.name = "Bob"; // obj2를 변경하면 obj1도 영향을 받음 

console.log(obj1.name); // "Bob" 
console.log(obj2.name); // "Bob"

 

obj1과 obj2는 같은 메모리 주소를 가리키고 있기 때문에, 한쪽을 변경하면 다른 쪽도 변경된다.

 

 

 

비교

특징 원시값 (Primitive) 참조값 (Reference)
저장 방식 값 자체 저장 메모리 주소(참조값) 저장
복사 방식 새 메모리 공간에 값 복사 (독립적) 같은 주소를 공유 (얕은 복사)
변경 가능 여부 불변(Immutable) 변경 가능(Mutable)

 

 

 

 

얕은 복사 (Shallow Copy)

객체를 복사할때 메모리주소(참조)만 복사해서 복사 시 같은 객체를 가리키게된다.

Object.assign()이나 spread 연산자 등을 사용할 경우 얕은 복사이다.

let obj1 = { name: "Alice" }; 
let obj2 = { ...obj1 }; // 얕은 복사

obj2.name = "Bob"; 
console.log(obj1.name); // "Alice" (영향 없음) 
console.log(obj2.name); // "Bob"

 

단, 객체 내부에 또 다른 객체가 있을 경우(중첩 객체)에는 내부 객체는 같은 참조를 공유하여 서로에게 영향을 준다.

 

let obj1 = { user: { name: "Alice" } }; 
let obj2 = { ...obj1 }; // 얕은 복사 

obj2.user.name = "Bob";

console.log(obj1.user.name); // "Bob" (내부 객체는 공유됨) 
console.log(obj2.user.name); // "Bob"

 

 

 

깊은 복사(Deep Copy)

객체의 모든 값을 새로운 메모리 공간에 복사하여 원본과 독립적인 객체를 생성하는 방법이다.

JSON.parse(JSON.stringify(obj)), structuredClone() 등을 사용할 경우 깊은 복사이다.

let obj1 = { user: { name: "Alice" } }; 

let obj2 = JSON.parse(JSON.stringify(obj1)); // 깊은 복사 

obj2.user.name = "Bob"; 
console.log(obj1.user.name); // "Alice" (영향 없음) 
console.log(obj2.user.name); // "Bob"

 

JSON.stringify() 방식은 undefined, Symbol, Function을 복사하지 못하는 단점이 있다.

라이브러리 사용(lodash DeepCole())이나 순회하여 복사하는 방법도 있다.

 

import lodash from "lodash"; 

const obj1 = { name: "Alice", address: { city: "Seoul" } }; 
const obj2 = lodash.cloneDeep(obj1); 

obj2.address.city = "Busan"; 

console.log(obj1.address.city); // "Seoul" (원본 영향 없음 ✅) 
console.log(obj2.address.city); // "Busan"

 

최신 브라우저는 structuredClone()를 사용할 수 있다.

let obj2 = structuredClone(obj1);

 

 

 

정리

구분 원시값 (Primitive) 참조값 (Reference)
메모리 저장 방식 값 자체 저장 메모리 주소 저장
변수 할당 시 값이 복사됨 (새로운 공간) 주소가 복사됨 (같은 객체 참조)
불변성(Immutable) ✅ (변경 불가) ❌ (변경 가능)
복사 방식 값이 독립적 같은 객체를 공유
예제 let a = 10; let b = a; let obj2 = obj1;

 

 

 

그렇다면 언제 어떤 방식을 사용해야할까?

방법 장점 단점 사용 추천
얕은 복사 (Object.assign(), spread 연산자) 빠르고 간단함 내부 객체가 공유됨 단순한 객체
JSON.stringify() + JSON.parse() 간단한 깊은 복사 undefined, Symbol, Function 복사 불가 기본 객체
structuredClone() 최신 방법, 빠르고 안전함 Node.js 미지원 브라우저에서 안전한 깊은 복사
_.cloneDeep() (lodash) 모든 타입을 안전하게 복사 라이브러리 필요 복잡한 객체, 대규모 프로젝트

 

 

 

반응형
최근에 올라온 글
최근에 달린 댓글
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Total
Today
Yesterday