1. 원시 값과 객체
원시 타입과 객체 타입의 근본적인 차이 3가지
- 변경 불가능한 값(immutable value) vs. 변경 가능한 값(mutable value)
- 확보된 메모리에 저장되는 실제 값 vs. 확보된 메모리에에 저장되는 참조 값
- 값에 의한 전달 vs. 참조에 의한 전달
1-1. 원시 값
1-1-1. 변경 불가능한 값
원시 값은 변경이 불가능한 값
→ 한번 생성된 원시 값은 읽기 전용 값
변경할 수 없다
변경할 수 없는 것은 값이지 변수가 아니다. 즉, 변수에 할당된 값이 변경이 불가능하다는 것이지 변수 자체는 재할당을 통해서 변경이 가능하다.
상수
상수는 변수의 상대 개념으로 재할당이 금지된 변수이다. 그 말은 상수에 할당된 값은 한번 할당되면 더 이상 바뀌지 못한다. 여기서 주의할 점은 상수라는 변수는 값을 교체할 수 없는 것 즉, 재할당이 금지된 변수이기 때문에 변경할 수 없는 값으로 동일시하면 안된다.
1-1-2. 불변성
- 변수 값을 변경하기 위해 새로운 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경
- 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없음
1-2. 문자열과 불변성
문자열은 원시 타입으로 정의
→ 변경이 불가능한 값
→ 문자열이 생성된 이후에는 변경할 수 없음
1-2-1. 문자열의 메모리 공간 크기
한 문자마다 정해진 메모리 요구 크기를 문자열에 포함된 문자 수만큼 곱하여 전체 문자열이 요구하는 메모리 공간의 크기를 정의
1-2-2. 문자열의 특성
- 유사 배열 객체
- 문자열은 마치 배열처럼 인덱스로 프로퍼티의 값에 접근 가능
- 문자열 또한 재할당을 통해서는 변수에 새로운 값으로 교체가 가능
var str = "Hello JavaScript!";
console.log(str[7]); // a
// length 프로퍼티를 가짐
console.log(str.length); // 17
str[7] = 'A';
console.log(str); // Hello JavaScript!
// 문자열은 변경 불가능한 값 -> A로 바뀌지 않음
2. 객체
- 정해져 있지 않고 동적으로 추가되거나 삭제될 수 있는 프로퍼티
- 프로퍼티의 값에도 제약은 없음
- 원시 값 처럼 확보해야 할 메모리 공간의 크기를 사전에 정할 수 없음
2-1. 변경 가능한 값
객체 타입의 값은 변경 가능한 값
→ 재할당 외에는 방법이 없는 변경 불가능한 값 원시 값과는 달리 객체는 재할당 없이 객체를 직접 변경할 수 있다.
2-1-1. 참조 값
객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값에 접근할 수 있따. 이때, 참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체이다. 그리고 이 참조 값을 통해 실제 객체에 접근을 하게 된다.
→ 객체를 할당한 변수에 재할당이 아닌 객체를 직접 수정하는 과정이므로 객체를 할당한 변수의 참조 값은 변경되지 않는다.
2-2. 객체는 왜 변경 가능한 값인가
객체를 변경할 때마다 원시 값처럼 이전 값을 복사해서 새롭게 생성한다면 명확하고 신뢰성이 확보되겠지만 객체는 크기가 매우 클 수도 있고, 원시 값처럼 크기가 일정하지도 않으며, 프로퍼티 값이 객체일 수도 있어서 복사해서 생성하는 비용이 많이 든다. 결국 메모리의 효율적 소비가 어렵고 성능이 나빠진다.
결국 메모리의 효율적 사용과 복사 시에 비용 절약, 그래서 성능을 향상시키기 위해서 객체는 변경 가능한 값으로 설계되어 있다.
그러나 이러한 구조에서 한 가지 단점이 존재하는데, 여러 개의 식별자가 하나의 객체를 공유할 수도 있다는 것이다.
2-2-1. 얕은 복사 와 깊은 복사
- 얕은 복사는 객체에 중첩되어 있는 객체의 경우 참조 값을 복사한다.
- 깊은 복사는 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 만든다.
2-3. 참조에 의한 전달
- 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.
- 두개의 변수는 저장된 메모리 주소는 다르지만 동일한 참조 값을 가진다.
- 결국 두 개의 식별자가 하나의 객체를 공유
- 결국 둘 중 하나라도 값을 바꾼다면 둘 모두에게 영향을 준다.
3. 공유에 의한 전달
식별자가 기억하는 메모리 공간, 그 변수에 저장되어 있는 값이 원시 값이냐 참조 값이냐의 차이만이 존재
-> "값에 의한 전달"과 "참조에 의한 전달"은 변수에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일
-> 결국 자바스크립트에는 "값에 의한 전달"만이 존재하는 것이다.
자바스크립트의 이러한 동작 방식을 "공유에 의한 전달" 이라고 표현한다.