정적 타입 언어
동적 타입 언어
원시타입
참조타입
변할 수 있는 데이터를 담는 공간(메모리)이다.
하지만 이 데이터 또한 메모리에 담긴다.
변수에 담기는 것은 데이터 메모리의 주소이다.
메모리의 실제 이름(주소는) 매우 복잡하기 때문에 알아보기 쉽게 별명을 단 것
모든 메모리는 본인의 이름(주소)를 가지고 있다
변수 메모리 (값의 메모리 주소를 담는 공간)
ㄴ 메모리 주소
ㄴ 식별자
ㄴ 데이터 메모리 주소를 담는 곳
데이터 메모리 (원시타입은 값, 참조타입의 경우 객체 변수 메모리 주소를 담음)
ㄴ 메모리 주소
ㄴ 값을 담는 곳
*값 할당이 되어야 생성됨
참조 타입 전용 변수 메모리 (여러 변수 메모리들을 담는 공간)
ㄴ 메모리 주소
ㄴ 변수
ㄴ 변수
...
*메모리 이름은 첫 변수의 메모리 이름이다
변수 메모리의 가변성
변수 메모리에 담기는 데이터 메모리 주소는 변경될 수 있다.
하지만 상수로 선언할 지 변경 불가능하다.
데이터 메모리의 불변성
데이터 메모리에 값이 한번 담기면 수정할 수 없다.
모든 중복되지 않는 값이 각각 다른 메모리에 담긴다.
아무도 참조하지 않는 데이터 메모리는 가비지 콜렉터가 제거한다.
왜 변수에 직접 값을 담지 않고 데이터 메모리를 한 번 더 거칠까?
한번 값을 할당하면 그 값에 맞춰 메모리 범위가 확보된다.
이미 확보된 데이터 메모리 공간을 할당되는 값에 크기에 맞춰 늘려야하는데,
다른 메모리들의 위치도 옮겨야 할 경우 컴퓨터가 할 연산이 많아지기 때문이다.
변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아진다.
매번 새롭게 메모리 크기를 정하고 안쓰는 것은 가비지 콜렉터가 처리하는게 더 효과적이다.
let a; // 변할 수 있는 데이터를 담는 메모리를 할당해줘. 그리고 그 메모리의 이름은 a로 해줘
let a = 10; // a메모리에 10할당해줘
선언 단계
할당 단계
*var는 선언 후 직후 undefind를 할당하고 let, const는 선언만 한 후에 코드 실행 시 초기 값 할당
3줄 요약
1. 변수 메모리 선언
2. 데이터 메모리에 값 할당
3. 변수에 데이터 메모리 주소 할당
이후 프로퍼티에 값 할당 시
*객체 변수 영역은 프로퍼티가 생길 때마다 크기가 동적으로 늘어남
원시타입 값은 데이터 메모리에 값이 담김
참조타입 값은 데이터 메모리에 객체 변수 메모리 주소가 담김
왜 원시 타입은 불변값, 참조타입은 가변값이라고할까?
=> 객체의 프로퍼티 변수의 값(메모리 주소)는 변경할 수 있기 때문에 가변적인 것처럼 보이는 것
공통점
원시, 참조 타입 모두 데이터 메모리의 주소가 복사된다는 점은 같다.
데이터 재할당 시에도 다른 값을 넣는다면 다른 데이터 메모리 주소를 새로 할당받기 때문에 문제가 없다.
차이점
문제는 참조타입의 프로퍼티 변수 값을 바꾸게 되면 참조 타입의 메모리 주소를 가지고 있는 모든 변수도 영향을 받는 다는 점이다.
어떤 데이터 타입이든 변수에 할당하기 위해서는 주솟값을 복사해야하기에 js의 모든 데이터 타입은 참조형 데이터일 수 밖에 없다. 원시타입은 주소 복사 과정이 한번만 이루어지고 참조타입은 주소 복사 과정이 한 단계 더 거치게 된다는 점이 다르다.
가변은 프로퍼티를 변경할 때만 성립.
매번 객체를 새로 만들고 프로퍼티를 재할당해야 불변성이 보존 됨.
불변객체가 왜 필요할까?
객체를 복사해서 사용할 때 원본 객체에 변경시키지 않아야 할 때 필요하다.
객체 외부 껍데기와 내부 프로퍼티까지 새롭게 복사되어야 한다.
불변 객체를 만드는 방법은 객체의 얕은 복사, 깊은 복사가 있다.
객체 복사 시 객체 껍데기와 프로퍼티를 재할당하는데, 바로 아래 단계의 값만 복사하는 것.
참조형 프로퍼티는 재할당하지 않고 메모리 주소를 복사하는 것.
방법1 - for in이용
방법2 - 전개 연산자 사용(1레벨에서만 유효)
내부의 모든 참조형 프로퍼티까지 재할당하여 복사하는 것.
방법1 - 원시 타입 데이터는 그대로 복사, 참조타입 데이터는 다시 내부 프로퍼티를 재귀적으로 복사해야함.
방법2 - JSON.parse(JSON.stringify(obj))
의 방식으로 구현할 수도 있다.
공통점 - 둘 다 값이 없다는 뜻이고 사용자가 직접 부여할 수 있다.
차이점 - undefined는 js엔진이 할당하는 경우가 있다.
→ 구분하기 위해 사용자가 직접 부여할 때는 null을 쓰는 게 좋다.
*객체의 키에 value를 안넣으면 오류가 나지만 배열은 갯수(인덱스)를 먼저 정할 수 있기 때문
자바스크립트는 콜스택과 메모리힙이라는 메모리 구조를 통해 데이터 및 코드 실행을 관리한다.
콜스택
1. 실행 컨텍스트 (변수 메모리)
메모리 힙
출처: https://curryyou.tistory.com/276?category=898979 [카레유:티스토리]