원시 자료형
- 원시 자료형은 읽기 전용으로, 변경 불가능한 값이다.
- 스택은 재할당되지 않으며, 삭제 권한은 가비지 컬렉터가 가진다.
- 원시 자료형은 메모리 공간에 값 자체가 저장된다.
- 원시 자료형을 다른 변수에 할당하면, 값 자체가 복사된다.
let a = 10;
let b = a; // b에는 a의 값 10이 복사된다.
b = 20; // b의 값은 20으로 변경되지만, a의 값은 여전히 10이다.
참조 자료형
- 참조 자료형은 다른 변수에 할당하면, 주소 값이 복사되어 전달된다.
- 참조 자료형은 변경 가능한 값이다.
- 배열의 요소 각각은 하나의 값이며, 최종 저장 공간 하나에 배열 자체를 저장하는 것은 불가능하다. 배열은 변수에 주소 값을 저장하여 참조 자료형에 접근한다.
- 배열 변수는 주소 값을 가지고 있으며, 이 주소를 통해 배열 요소에 접근한다. 원시 타입 요소는 그대로 저장되고, 참조 타입 요소는 또 다른 주소 값을 가진다.
let obj = { name: "Alice" };
let arr = [1, obj];
let arrCopy = arr; // arrCopy는 arr의 주소 값을 복사받는다.
arrCopy[0] = 99; // arr[0]도 99로 변경된다.
obj.name = "Bob"; // arr[1].name과 arrCopy[1].name 모두 "Bob"으로 변경된다.
배열 복사
- 같은 요소를 가진 배열을 할당한다고 해서 같은 배열의 주소 값을 가지지는 않는다.
- 참조 타입(배열)을 그냥 할당하면 주소 값만 복사된다.
- 배열을 복사하려면 slice() 메서드나 spread syntax(...)를 사용하거나, for 문으로 각 인덱스에 접근해 각각 대입해야 한다. 이는 한 단계까지만 복사하는 얕은 복사이다.
- 레퍼런스 타입의 레퍼런스 타입을 안고 있으면, 깊은 복사로도 안 되며, 깊은 깊은 복사가 필요하다. 가능한 경우 JSON으로 변환했다가 다시 돌리면 가장 간단하게 깊은 복사가 가능하다.
얕은 복사 예시:
let original = [1, 2, { name: "Alice" }];
let shallowCopy = original.slice(); // 또는 [...original]
shallowCopy[2].name = "Bob"; // original[2].name도 "Bob"으로 변경된다.
깊은 복사 예시:
let original = [1, 2, { name: "Alice" }];
let deepCopy = JSON.parse(JSON.stringify(original));
deepCopy[2].name = "Bob"; // original[2].name은 여전히 "Alice"이다.
원시자료형은 변수를 다른 변수에 할당하면 값자체의 복사가 일어남.