티스토리 뷰

반응형

[챗지피티와 공부를 해보자] 원시값(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) 모든 타입을 안전하게 복사 라이브러리 필요 복잡한 객체, 대규모 프로젝트

 

 

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
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
글 보관함