본문 바로가기
▼ 코딩 공부하기/▼▼ 프론트엔드

💻 JavaScript 얕은 복사와 깊은 복사, var, let, const 비교 (feat. 왕초보 위클리 페이퍼 #4)

by mdeeno 2025. 12. 21.
반응형

안녕하세요! 개발자 꿈나무 엠디노입니다.

현재 '웹개발 풀스택' 과정을 훈련하고 있습니다.

 

이번 주차 위클리 페이퍼 주제는 자바스크립트를 다루면서 가장 실수하기 쉬운, 그래서 면접에서도 집요하게 물어보는 두 가지 개념입니다.

 

"복사하면 그냥 복사되는 거지, 얕은 건 뭐고 깊은 건 뭐야?"

"var는 왜 쓰지 말라는 거야? 작동은 잘 되던데?"

 

저와 같은 의문을 가졌던 분들을 위해, 7살도 이해할 수 있는 쉬운 비유 실제 코드 예시를 통해 아주 상세하게 파헤쳐 보았습니다.

 

 

⭐️  위클리 페이퍼 #1-CSS Cascading, 시맨틱 태그 [바로가기] ⭐️

 

웹 개발로 전향 후 깨달은 것: CSS Cascading과 시맨틱 태그 알아보기 (feat. 왕초보 위클리 페이퍼 #1)

안녕하세요! 개발자 꿈나무 엠디노입니다.건축, 도시계획에만 근 10년을 매진하다가더 나은 미래를 위해 '웹개발 풀스택' 과정을 훈련하고 있습니다.(앞으로 7개월... 화이팅하자..) 훈련 중 첫 번

dino.mdeeno.com

 

⭐️  위클리 페이퍼 #2-GIT merge, GIT flow branch 전략 [바로가기] ⭐️

 

💻 Git branch merge, Git flow Branch 전략 알아보기 (feat. 왕초보 위클리 페이퍼 #2)

안녕하세요! 개발자 꿈나무 엠디노입니다.지난 포스팅에서 말한 것처럼 '웹개발 풀스택' 과정을 훈련하고 있습니다.(벌써 2주나 해버린!) 이번에는 '위클리 페이퍼 #2'를 포스팅하고자 합니다.혹

dino.mdeeno.com

 

⭐️  위클리 페이퍼 #3-This, 렉시컬 스코프 [바로가기] ⭐️

 

💻 JS This, 렉시컬 스코프 개념 전 알아보기 (feat. 왕초보 위클리 페이퍼 #3)

안녕하세요! 개발자 꿈나무 엠디노입니다.현재 '웹개발 풀스택' 과정을 훈련하고 있습니다. 이번에는 '위클리 페이퍼 #3'를 포스팅하고자 합니다. 앞서 작성한 포스팅이 궁금하시다면 아래 링크

dino.mdeeno.com

 

 

 

각설하고 바로 시작하겠습니다.

 


 

⭐️ 위클리 페이퍼 주제

  • 얕은 복사(Shallow Copy)깊은 복사(Deep Copy)의 작동 원리와 차이점
  • var, let, const의 스코프(유효범위) 및 차이점 심층 분석

 


1. 얕은 복사(Shallow) vs 깊은 복사(Deep)

자바스크립트에서 객체(Object)배열(Array)은 메모리에 저장되는 방식이 일반 변수(숫자, 문자열)와 다릅니다.

이 차이 때문에 '복사'를 할 때 우리가 예상치 못한 대참사(Side Effect)가 발생하곤 합니다.

 

🐣  7살 버전: 우리 집 열쇠 vs 똑같은 새 집

1. 얕은 복사 (Shallow Copy)

친구에게 "우리 집 열쇠(주소)"를 복사해서 줬어요. 친구가 그 열쇠로 우리 집에 들어와서 TV를 부셨어요. 그럼 내 TV도 부서진 거죠? (같은 집이니까요!)

 

2. 깊은 복사 (Deep Copy)

우리 집이랑 "완전히 똑같이 생긴 새 집"을 옆에 지어서 친구에게 줬어요. 친구가 자기 집 TV를 부셨어요. 내 집 TV는 멀쩡하죠? (완전히 다른 집이니까요!)

 

💻  핵심: 주소값을 공유하느냐, 새로 만드느냐

아래 이미지는 메모리 상에서 데이터가 어떻게 복사되는지를 시각적으로 보여줍니다. 얕은 복사는 결국 같은 곳을 바라보는 화살표만 하나 더 만드는 셈입니다.

 

 

1) 얕은 복사 (Shallow Copy)의 위험성

얕은 복사는 객체의 가장 바깥쪽 껍데기만 새로 만들고, 그 안에 들어있는 물건들(중첩된 객체)은 원본과 공유합니다. Object.assign()이나 ... (전개 연산자)가 이에 해당합니다.

 

const 원본 = {
  이름: "엠디노",
  성적: { 수학: 100, 영어: 90 } // 객체 안에 또 객체가 있음
};

// 얕은 복사 시도 (... 스프레드 연산자 사용)
const 복사본 = { ...원본 };

// 복사본의 성적을 0점으로 바꿔보겠습니다.
복사본.성적.수학 = 0;

console.log(복사본.성적.수학); // 0 (당연함)
console.log(원본.성적.수학);   // 0 (!!! 으악 원본도 0점이 됨)

 

2) 깊은 복사 (Deep Copy)의 해결책

깊은 복사는 객체 내부의 모든 깊이(Depth)까지 파고들어서 완벽하게 새로운 데이터를 만듭니다. 원본과 복사본은 완전히 남남이 됩니다.

// JSON 방법: 객체를 문자열로 바꿨다가(stringify) 다시 객체로 만듦(parse)
const 깊은복사본 = JSON.parse(JSON.stringify(원본));

깊은복사본.성적.수학 = 50;

console.log(깊은복사본.성적.수학); // 50
console.log(원본.성적.수학);       // 100 (안전하게 보존됨!)

* 참고: 최신 자바스크립트에서는 structuredClone(원본)이라는 더 좋은 함수도 사용할 수 있습니다.

 


2. var, let, const 비교

"셋 다 변수 만드는 건데 대충 쓰면 안 되나요?" 네, 안 됩니다.

이 셋의 가장 큰 차이는 "유효 범위(Scope)""재할당 가능 여부"에 있습니다. 

 

 

🐣  7살 버전: 장난감 상자의 규칙

1. var (동네방네 소문난 상자)

방 안에 상자를 뒀는데, 거실에서도, 부엌에서도 다 보여요. 심지어 똑같은 이름의 상자를 또 만들어도 아무도 뭐라 안 해요. 나중에 헷갈려서 엉망이 돼요! (쓰지 마세요🙅‍♂️)

 

2. let (내 도시락 통)

내 가방(블록) 안에 쏙 들어있어서 밖에서는 안 보여요. 오늘은 사과를 넣었다가, 내일은 바나나로 바꿔 넣을 수 있어요. (내용물 교체 가능!🙆‍♂️)

 

3. const (박물관 유리 상자)

한 번 물건을 넣고 잠그면 끝! 다른 걸로 못 바꿔요. 깨지지 않는 약속과 같아요. (교체 불가능!🔒)

 

💻  1. var (The Zombie)

var는 ES6(2015년) 이전에 쓰이던 방식으로, 치명적인 단점인 함수 레벨 스코프를 가집니다.

if (true) {
  var 좀비 = "살아있다";
}

// if문이 끝났는데도 변수가 살아있음 (블록을 무시함)
console.log(좀비); // "살아있다" 출력

 

💻  2. let과 const (The Guardians)

이 둘은 블록 레벨 스코프 {}를 따릅니다. 즉, 중괄호 안에서 만든 변수는 밖으로 절대 새어나가지 않습니다.

if (true) {
  let 유령 = "여기서만 존재해";
}

console.log(유령); // ReferenceError: 유령 is not defined (안전함!)

 

⚠️ 주의! const로 만든 객체는 바뀔 수 있다?

이 부분이 많이 헷갈리는데, const는 '변수 자체(주소)'를 못 바꾸게 하는 것이지,

그 안에 있는 '내용물' 수정을 막는 건 아닙니다.

const 내지갑 = { 돈: 1000 };

내지갑 = { 돈: 5000 }; // 에러! (지갑 자체를 바꿀 순 없음 - 재할당 금지)
내지갑.돈 = 0;         // 가능! (지갑 안의 내용물은 변경 가능)

 

🔥 최종 요약 및 실무 팁

 

1. 기본적으로 const를 쓰세요. (값이 안 바뀌는 게 코드 흐름을 예측하기 가장 좋습니다)

2. for문이나 값이 변경되어야 하는 경우에만 let으로 바꾸세요.

3. var는... 이제 그만 놓아주세요. (레거시 코드 해석할 때만 알면 됩니다)

 


 

종합 정리

 

 

이상 개발자 꿈나무 엠디노였습니다...

머지않아 또 다른 숙제와 문제 해결 과정으로 찾아뵙겠습니다..

 

그럼 이만!

반응형