1. 자료형
⚡️ 데이터의 두가지 타입
- 데이터의 타입은 원시 자료형(primitive type)과 참조 자료형(reference type)이 있다.
- 원시 자료형이 할당 될때에는 변수에 값(value) 자체가 담긴다.
- 참조 자료형이 할당 될때에는 보관함의 주소(reference)가 담긴다.
⚡️원시 자료형(Primitive type)
- 원시자료형이란 하나의 보관함에 하나의 데이터만을 담고 변수의 이름으로 저장하는 것을 말한다.
- 원시 자료형에는 6가지의 타입이 있다.
- string, number, boolean, undefined, symbol, bigint, null
- string : 'WONHO'
- number : 19930215
- boolean : true / false
- undefined : 변수가 정의되지 않았거나 값이 없는 경우
- bigint : 9007199254740991n
- null : 의도적으로 비어있는 공간을 표시하기 위함
- 값이 변하지 않는 불변성(immutable)을 갖고 있다.
- 따라서, 재할당 시 기존 값이 변하는 것처럼 보일지라도, 사실 새로운 메모리에 재할당한 값이 저장되고 변수가 가르키는 메모리가 달졌을 뿐인 것이다.
- (데이터 복사가 일어날 때 메모리 공간을 새로 확보하여 독립적인 값을 저장)
⚡️ 참조 자료형(Reference type)
- 자바스크립트에서는 원시 자료형이 아닌 모든것을 참조 자료형이라고 한다.
- 배열과 객체, 함수가 대표적인 참조 자료형이다.
- 참조 자료형은 변수에 할당할 때 값을 저장하는 것이 아닌 주소를 저장한다.
- 변수는 주소를 저장하고, 주소는 특별한 동적인 데이터 보관함(Heap)에 보관된다.
- 값을 재할당 할 경우 해당 주소를 참조한 모든 값이 영향을 받는다. (= 즉, 값이 공유되는 특성을 지닌다.)
❗️ 요약
원시 자료형(Primitive type) | 참조 자료형(Reference type) |
고정된 저장공간 | 동적인 저장공간 |
하나의 데이터만 담음 | 여러개의 데이터를 담음 |
할당시 '값'만 복사 (다른 변수에 복사 후 변경해서, 원본은 변경 X) ( immutable ) |
할당시 '주소'까지 복사 (다른 변수에 복사 후 변경시, 기존 변수까지 변경됨) ( mutable ) |
ex) string, number, boolean, undefined, symbol, bigint, null | ex) 배열, 객체 , 함수 등 |
2. 얕은 복사와 깊은 복사
⚡️ 얕은 복사(shallow copy)란?
- 참조 타입 데이터가 저장한 '메모리 주소 값'을 복사한 것을 의미한다.
- 얕은 복사는 참조 복사와 객체 복사로 나눌 수 있다.
❗️ 얕은 복사 _ 참조 복사
// 얕은복사_참조복사 예시
let obj1 = { a: 1, b: 2, c: 3};
let obj2 = obj1;
console.log( obj1 === obj2 ); // true
- 위의 예시와 같이 객체를 직접 대입하는 경우 참조에 의한 할당이 이루어 지기 때문에, 둘은 같은 주소를 가지고 있다.
- 이것이 얕은 복사(참조 복사)이다.
let obj1 = { a: 1, b: 2, c: 3};
let obj2 = obj1;
console.log( obj1 === obj2 ); // true
obj2.a = 1000;
console.log( obj1.a ); // 1000
- 위 두 객체는 같은 주소(데이터)를 가지고 있다.
- 따라서, obj2의 property를 수정하고, obj1을 출력해도 obj2값과 동일하다.
❗️ 얕은 복사 _ 객체 복사
- 방법1. ...(spread) 연산자를 통한 복사
let obj1 = { a: 1, b: 2, c: [3, 4]};
const obj2 = { ...obj1 };;
console.log( obj1 === obj2 ); // false
obj2.a = 1000;
console.log( obj1.a ); // 1
console.log( obj1.c === obj2.c ) // true
obj2.c[0] = 33;
console.log( obj1.c[0] ) = 33; // 객체 내 배열의 값은 같은 주소를 참조하기 때문에
// obj2.c[0]을 변경하면 obj1.c[0]의 값도 변경됨
- ...(spread) 연산자를 통해 obj1의 속성을 복사하여 obj2에 할당하였다.
- obj1과 obj2는 다른 주소를 갖게 되었으나, 객체 속의 배열 c: [3, 4]는 동일한 주소값을 공유한다
- 방법2. Object.assign() 메서드를 통한 복사
let obj1 = { a: 1, b: 2, c: [3, 4]};
let obj2 = Object.assign({}, obj1)
obj2.a = 1000;
console.log( obj1 === obj2 ) /// false
console.log( obj1.a ); // 1
console.log( obj1.c === obj2.c ) // true
obj2.c[0] = 33;
console.log( obj1.c[0] ) = 33; // 객체 내 배열의 값은 같은 주소를 참조하기 때문에
// obj2.c[0]을 변경하면 obj1.c[0]의 값도 변경됨
- Object.assign() 메서드를 이용하여 첫번째 인자로 빈 객체를, 두번쨰 인자로 obj1을 넣어 obj2에 할당 하였다.
- obj1과 obj2는 다른 주소를 갖게 되었으나, 객체 속의 객체 c: [3, 4]는 동일한 주소값을 공유한다
⚡️ 깊은 복사(deep copy)란?
- 새로운 메모리 공간을 확보하여 완전히 복사하는 것을 의미한다.
- 얕은 복사 처럼 주소를 복사하여 공유하는 것이 아닌, 아예 새로운 객체안 속성만 복사하는 것이다.
⚡️ 완벽한 Deep copy 방법
- 위 2가지 방법 (spead 연산자와 Object.assign 메서드) 모두 Shallow copy 이다.
- JSON.parse()와 JSON.stringify()함수를 사용하면 Deep copy 구현이 가능하다.
- 하지만, 위의 방법도 객체 내부에 함수가 포함된다면 함수의 값이 null로 바뀌게 되어 사용할 수 없다.
- 따라서 lodash, ramda, 및 rdfc 등의 외부 라이브러리를 이용하여야 한다 (추후 업로드 예정)
Reference
'코딩 > 코드스테이츠 45기(FE)' 카테고리의 다른 글
블로깅 챌린지 4주차 - [JS/브라우저]DOM / [실습]유효성 검사 (0) | 2023.05.04 |
---|---|
블로깅 챌린지 4주차 - [JS] koans 리뷰 (0) | 2023.05.02 |
블로깅 챌린지 3주차 - [JS] 배열, 객체 (0) | 2023.04.25 |
블로깅 챌린지 10일차 - [Linux/Git] 기초 (0) | 2023.04.24 |
블로깅 챌린지 9일차 - 계산기 기능 구현 (0) | 2023.04.21 |