데이터 타입
기본형(원시형)
- 숫자, 문자열, boolean, null, undefined, ES6 이후 심볼 추가
- 할당이나 연산시 복제된다.
- 기본형은 값이 담긴 주솟값을 바로 복제
- 기본형은 모두 불변값
참조형
- 객체, 배열, 날짜, 정규표현식, ES6 이후 map, set
- 할당이나 연산시 참조된다.
- 참조형은 값이 담긴 주솟값들도 이루어진 묶음을 가리키는 주솟값을 복제
메모리 구조
실제 자바스크립트의 메모리 구조
--> 지정된 공간보다 데이터가 더 추가되면 메모리는 어떻게 되는지?
변수
식별자
메모리 주솟값
- 0, 1만 표현할 수 있는 하나의 메모리 조각을 비트라고 함
- 각 비트는 고유한 식별자를 통해 위치를 확인할 수 있다.
- 효율적인 검색을 위해 비트를 묶어 바이트로 만듦
- 모든 데이터는 바이트 단위 식별자, 메모리 주솟값을 통해 서로 구분하고 연결할 수 있다.
- 식별자는 어떤 데이터를 식별하는 데 사용하는 이름, 즉 변수명이다.
선언과 할당
let a; // 변수 a를 선언 or 이 데이터의 식별자는 a로 한다
a = "abc" // 변수 a에 데이터 할당
let a = "abc" // 변수 선언과 할당을 한 문장으로 표현
- 변수를 선언하면 컴퓨터는 메모리의 빈 공간에 식별자를 저장하고, 그 공간의 값은 undefined를 할당한다.
- 그 변수에 기본형 데이터를 할당하려고 하면 별도의 공간에 데이터를 저장, 그 공간의 주소를 변수의 값 영역에 할당.
- 참조형 데이터를 할당하고자 할 경우 참조형 데이터 내부 프로퍼티들을 위한 변수 영역을 별도로 확보해서 확보된 주소를 변수에 연결, 다시 확보한 변수 영역에 각 프로퍼티의 식별자를 저장하고, 각 데이터를 별도의 공간에 저장해 그 주소를 식별자들과 매칭
기본형 데이터 할당 과정
- [주소, 데이터] 로 묶인 셀(key, value) 있고 선언된 식별자 (여기서는 var a)를 key로 줌.
- 식별자에 값을 할당하게 되면 (var a = 'abc') 다른 메모리에 저장하고 변수 a가 가리키는 주소의 값으로 할당된 값이 저장된 주소를 줌
- 여기서 변수 a에 다른 값을 할당하면 다른 메모리 주소에 할당하고 변수 a가 가리키는 주소의 값을 변경
참조형 데이터 할당 과정
var obj = {
a: 1,
b: "abx"
}
- 위처럼 써도 컴퓨터는 선언과 할당을 분리함. 기본형과 동일하게 메모리에 키(이름)에 식별자 저장한다
- 객체의 프로퍼티를 저장해야 하는데, 메모리는 하나의 값만 저장된다. 그래서 메모리를 하나 확보하고 그 메모리에서 다시 일정한 구간의 메모리들을 확보한다.
- 가령 1002에 [이름:obj, 값: 5002], 그리고 5002에서 obj에 대한 메모리 구역을 확보, 5003에 1할당, 7103에 [이름:a, 값 @5003] 으로 할당하는 식.
obj.a = 2
- 위처럼 새로운 값을 할당하게 되면 우선 5005에 [2]을 만듦. 이제 obj.a를 찾으면 obj가 5002를 가리키고 있고 5002로 가면 7103이 있고. 7103에 있는 a 프로퍼티를 찾음
- 7103의 주소를 5005로 바꿈
즉, 기본형의 경우는 주소값이 변하지만 참조형에서 프로퍼티 값을 변경하면 주소는 변하지 않음.
가비지 컬렉터
- 중첩 객체의 경우, 참조 할당 과정을 두 번 거침
- 만약 중첩 객체였던 프로퍼티에 [3, 4, 5] 를 'str'으로 할당하게 되면 주소값이 변경되면서 기존의 [3, 4, 5]에 대한 참조 대상이 사라짐. 이렇게 되면 GC에 수거대상이 됨
불변 객체
- 참조형 데이터의 '가변'은 데이터 자체가 아니라 내부 프로퍼티를 변경할 때만 성립된다.
복사
var a = 10
var b = a
-기본형의 경우, 둘 다 동일한 주소값을 가지게 됨
- 동일하게 참조형의 경우에도 둘 다 동일한 주소값을 가지게 됨
하지만 변경 시에는 다름
b = 15
obj2.c = 20
- 불변의 경우 a, b가 보는 주소값이 달라짐
- 참조의 경우, obj2가 보는 주소값이 아니라, 내부 프로퍼티가 보는 주소값을 변경하는 것이기 때문에 obj1, obj2는 여전히 같은 주소를 봄 --> 원본 객체의 값이 같이 변경됨
기본형은 주소값을 복사하는 과정이 한번, 참조형은 한 단계 더
얕은 복사와 깊은 복사
- 얕은 복사는 바로 아래 단계만 복사, 깊은 복사는 내부의 모든 값들을 하나하나 다 복사
- 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사한다는 의미
- 그러므로 해당 프로퍼티에 대해 원본과 사본이 모두 동일한 참조형 데이터의 주소를 가리키게 된다.
- 깊은 복사는 참조형 데이터의 경우 다시 그 내부의 프로퍼티들을 복사해야 한다.
undefined와 null
- 사용자가가 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제 값이 없을 때 undefined 반환
- null은 사용자가 명시적으로 "없음"을 나타내기 위해 대입한 것
참고 : 코어자바스크립트