코딩.zip
[객체&배열] 딱복? 물복?의 시대는 갔다 얕복 vs 깊복의 차이를 알아보자 (얕은 복사, 깊은 복사) 본문
▶ 얕은 복사(shallow Copy)
주소값(참조값)을 복사해서 복사본과 원본 모두 영향을 미침
<script>
const object_202403 = ['우유', '식빵']
// 얕은 복사 : 객체의 주소값을 복사
const object_202404 = object_202403
object_202404.push('딸기잼')
object_202404.push('커피')
console.log(object_202403)
console.log(object_202404)
</script>
<!-- 실행 결과
(4) ['우유', '식빵', '딸기잼', '커피']
(4) ['우유', '식빵', '딸기잼', '커피']
-->
🚨 잠깐, const로 선언된 변수는 상수값을 가지는데 어떻게 요소를 추가 했을 때 Error가 뜨지 않았을까?
const로 선언된 변수는 재할당이 불가능한 상수이다. 그러나 const로 선언된 객체(배열 포함)는 객체의 내부 요소가 변경될 수 있다.
얕은 복사(shallow copy)는 객체의 주소값을 복사해서 새로운 변수에 할당하기 때문에 object_202404가 object_202403와 같은 객체를 참조하고 있다.
▶ 깊은 복사(deep Copy)
실제값을 새로운 메모리에 복사해서 완전히 새로운 객체 생성
<script>
const object_202403 = ['우유', '식빵']
// 깊은 복사 : 객체의 실제 값을 복사
const object_202404 = [...object_202403]
object_202404.push('딸기잼')
object_202404.push('커피')
console.log(object_202403)
console.log(object_202404)
</script>
<!-- 실행 결과
(2) ['우유', '식빵']
(4) ['우유', '식빵', '딸기잼', '커피']
-->
깊은 복사(deep copy)를 사용하면 주소값이 아닌 객체의 실제 내용을 복사하게 되고, 이 경우 두 변수는 서로 독립적으로 처리되어 새로운 요소 추가 시 원본값은 변하지 않는다.
✅ 전개 연산자(spread Operator)
배열이나 객체의 요소를 펼쳐서 새로운 배열이나 객체를 생성할 때 사용
표현 방법 : '...객체명'
- 배열(array)의 전개 연산자
<script>
const object_202403 = ['우유', '식빵']
// 고구마가 인덱스[0]이 되고 토마토가 인덱스[4]가 된다.
const object_202404 = ['고구마', ...object_202403, '토마토']
console.log(object_202403)
console.log(object_202404)
</script>
<!-- 실행 결과
(2) ['우유', '식빵']
(4) ['고구마', '우유', '식빵', '토마토']
-->
'...object_202403' : object_202403 배열의 모든 요소를 펼쳐서 새로운 배열 object_202404 를 만든다는 뜻
- 전개 연산자 위치에 따라 인덱스 결과가 달라지는 것을 기억해야 한다. 만약 [...object_202403, '고구마', '토마토'] 순서였다면 실행 결과값이 ['우유', '식빵', '고구마', '토마토']로 달라졌을 것이다.
- 객체(object)의 전개 연산자
<script>
const 송이 = {
이름 : '송이',
나이 : 12,
종류 : '강아지'
}
const 코코 = {
...송이,
이름 : '코코',
나이 : 5,
예방접종:true
}
console.log(JSON.stringify(송이))
console.log(JSON.stringify(코코))
</script>
<!-- 실행 결과
{"이름":"송이","나이":12,"종류":"강아지"}
{"이름":"코코","나이":5,"종류":"강아지","예방접종":true}
-->
'...object_202403' : object_202403 객체의 모든 속성을 펼쳐서 새로운 객체 object_202404 를 만든다는 뜻
→ 객체에서의 전개 연산자도 어디에 위치 시키느냐에 따라 결과값이 아예 달라질 수 있다.
<script>
const 송이 = {
이름 : '송이',
나이 : 12,
종류 : '강아지'
}
// 전개 부분을 마지막에 작성
const 코코 = {
이름 : '코코',
나이 : 5,
예방접종:true,
...송이
}
console.log(JSON.stringify(송이))
console.log(JSON.stringify(코코))
</script>
<!-- 실행 결과
{"이름":"송이","나이":12,"종류":"강아지"}
{"이름":"송이","나이":12,"예방접종":true,"종류":"강아지"}
-->
- 코코 객체를 생성 후 '...송이' 객체를 마지막에 전개 했을 때, 코코 객체가 송이 객체 속성들을 덮어쓰게 된다.
- 또한 송이 객체에 없는 '예방접종:true' 속성을 새로 생성하였기 때문에 결과값에 추가되며
- 송이 객체에서 가져온 '종류:강아지'는 전개 연산자 위치에 의해 맨 마지막에 추가되어 결과값에 나타난다.
처음에 '...'만 보고 나머지 매개변수인줄 알았다.. 그래서 혹시나 나 같은 사람이 있을까봐^^ 두 개 구분하는 방법을 찾아보았다.
함수 호출 시 사용 → 배열을 목록으로 확장해주는 전개 연산자
함수 매개변수의 끝에 위치 → 인수 목록의 나머지를 배열로 모아주는 나머지 매개변수
출처: https://inpa.tistory.com/entry/JS-📚-전개-연산자Spread-문법 [Inpa Dev 👨💻:티스토리]

나 구분 할 수 있겠지..(응 해야지.
'프로그래밍 > JavaScript' 카테고리의 다른 글
[클래스] 자바스크립트 클래스(class)와 상속(inheritance)을 알면 객체지향이 쉬워질 것 (0) | 2024.04.15 |
---|---|
[클래스] private, static / getter, setter (0) | 2024.03.12 |
[함수] 자바스크립트 callback 함수 다루기( forEach, map, filter ) + 화살표 함수 (0) | 2024.03.06 |
[조건문] if문과 switch문은 언제 사용할까? (0) | 2024.03.04 |