오늘은 원시 자료형, 참조 자료형의 종류와 특징에 대해 공부했다.
또 얕은 복사와 깊은 복사에 대해서도 알아봤다.
원시 자료형은 고정된 저장 공간을 차지한다.
원시 자료형의 종류
number
string
boolean
undefined
null
symbol
참조 자료형은 데이터를 다루기에 적합한 배열과 객체 등의 자료
1.참조 자료형을 변수에 할당하면 메모리 공간에 주솟값이 저장된다.
2.참조 값을 갖는 변수를 다른 변수에 할당하면 주솟값이 복사되어 전달된다.
3.참조 자료형은 변경이 가능한 값이다.
참조 자료형의 종류
array
object
function
복사하려는 원복 객체에 대해서 새로운 단일 객체 또는 새로운 복합 객체를 만들고 원본 객체를 참조한다.
배열 내장 메서드인 slice()를 사용하면 원본 배열을 복사할 수 있다.
let arr = [0, 1, 2, 3];
let copiedArr = arr.slice();
console.log(copiedArr); // [0, 1, 2, 3]
console.log(arr === copiedArr); // false
새롭게 생성된 배열은 원본 배열과 같은 요소이지만 참조하고 있는 주소는 다르다. 그래서 복사한 배열에 요소를 추가해도 원본 배열에는 추가되지 않는다.
copiedArr.push(4);
console.log(copiedArr); // [0, 1, 2, 3, 4]
console.log(arr); // [0, 1, 2, 3]
배열이 할당된 변수 앞에 ...
을 붙여 배열을 펼칠 수 있다.
let arr = [0, 1, 2, 3];
console.log(...arr); // 0 1 2 3
같은 요소를 가진 배열 두 개를 만들고 다른 변수에 각각 할당한다면, 같은 주소를 참조하지 않고 다른 주소를 참조한다.
let num = [1, 2, 3];
let int = [1, 2, 3];
console.log(num === int) // false
spread syntax는 배열뿐만 아니라 객체를 복사할 때도 있다. 하지만 참조 자료형 내부에 참조 자료형이 중첩되어 있는 경우, slice(), spread syntax, Object.assign()을 사용해도 복사를 할 수 없다.
객체를 복사하기 위해서 Object.assing()을 사용한다.
let obj = { firstName: "coding", lastName: "kim" };
let copiedObj = Object.assign({}, obj);
console.log(copiedObj) // { firstName: "coding", lastName: "kim" }
console.log(obj === copiedObj) // false
참조 자료형 내부에 중첩되어 있는 모든 참조 자료형을 복사하는 것은 깊은 복사라고 한다. Javascript 내부적으로 깊은 복사를 수행할 수 없다. 그래서 JSON.stringfy()와 JSON.parse()를 이용한다.
JSON.stringify()는 참조 자료형을 문자열 형태로 변환하여 반환하고, JSON.parse()는 문자열의 형태를 객체로 변환하여 반환합니다. 먼저 중첩된 참조 자료형을 JSON.stringify()를 사용하여 문자열의 형태로 변환하고, 반환된 값에 다시 JSON.parse()를 사용하면, 깊은 복사와 같은 결과물을 반환합니다.
const arr = [1, 2, [3, 4]];
const copiedArr = JSON.parse(JSON.stringify(arr));
console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false