JavaScript 원시형(Primitive) 타입과 참조형(Reference) 타입
JavaScript의 데이터 타입은 원시형(Primitive)과 참조형(Reference) 두 가지 유형으로 분류된다.
데이터 타입은 다음과 같다:
- 원시형 타입:
String
,Number
,Undefined
,Null
,Symbol
,Boolean
- 참조형 타입:
Object
,Array
,Function
,Date
원시형 타입
코드에서 변수 str2
의 값 'hello'
를 'world'
로 수정하는 거처럼 보이지만 사실 수정하는 게 아니라 'hello'
는 메모리 영역에 그대로 남아 있고 'world'
를 새로 만들어 메모리 영역에 저장한다.
이처럼 원시형 타입은 메모리 상에 한 번 만들어지면 바뀌지 않는 성질(불변성) 을 가지고 있다.
위의 코드가 전부 실행됐을 때의 메모리 영역을 보면:
메모리 | - | - | - | - |
---|---|---|---|---|
주소 | 1001 | 1002 | 1003 | 1004 |
데이터 | 이름:str1 값:@5003 | 이름:str2 값:@5004 | 이름:str3 값:@5003 | |
주소 | 5001 | 5002 | 5003 | 5004 |
데이터 | 'hello' | 'world' |
처음엔 변수 str1
를 변수 str2
에 복사해 두 변수의 값은 @5003의 문자열 데이터 'hello'
를 참조하고 있다가, 변수 str1
에 문자열 데이터 'world'
를 재할당하면 @5004에 world
문자열 데이터를 저장하고 변수 str2
는 @5004의 문자열 데이터 'world'
를 참조하게 된다.
추가로 변수 str3
에 'hello'
를 할당하면 메모리 상에 이미 'hello'
가 있기에 새로 만들지 않고 @5003을 참조한다.
참조형 데이터
코드에서 복사 된 변수 obj2
의 객체 프로퍼티 값을 재할당하거나 추가하면 변수 obj
도 같이 변하는 것으로 볼 수 있다.
이처럼 참조형 타입은 메모리 상에서 가변성을 띄고 있다.
메모리 영역을 살펴보면:
메모리 | - | - | - | - |
---|---|---|---|---|
주소 | 1001 | 1002 | 1003 | 1004 |
데이터 | 이름:obj 값:@5001 | 이름:obj2 값:@5001 | ||
주소 | 5001 | 5002 | 5003 | 5004 |
데이터 | @7001~ ? | 'mt' | 'jake' | 31 |
주소 | 7001 | 7002 | 7003 | 7004 |
데이터 | 이름:name 값:@5003 | 이름:age 값:@5004 |
메모리 영역을 보면 변수 obj
는 객체의 주소 값(@7001~ ?)를 참조하고 있다. 그리고 해당 객체의 프로퍼티 값들은 각각 @5003, @5004를 참조하고 있다. 다시 되짚어 보면 변수 obj
를 복사한 변수 obj2
의 객체 프로퍼티 값을 변경하거나 추가하면 원본 변수 obj
의 객체 프로퍼티 값도 변하기 때문에 부작용에 주의해야 한다.
*더 이상 참조되지 않는 @5002의 문자열 데이터 'mt'는 추후에 자바스크립트 가비지 컬렉터에 의해 비워지고 빈 공간이 된다.
참조형 타입에 대해 조금 더 알아 보면
obj
와 obj3
가 같은 줄 알았지만 그렇지 않았다.
메모리 | - | - | - | - |
---|---|---|---|---|
주소 | 1001 | 1002 | 1003 | 1004 |
데이터 | 이름:obj 값:@5001 | 이름:obj2 값:@5001 | 이름:obj3 값:@5002 | |
주소 | 5001 | 5002 | 5003 | 5004 |
데이터 | @7001~ ? | @8001~ ? | 'mt' | |
주소 | 7001 | 7002 | 7003 | 7004 |
데이터 | 이름:name 값:@5003 | |||
주소 | 8001 | 8002 | 8003 | 8004 |
데이터 | 이름:name 값:@5003 |
메모리 영역을 보면 obj3
는 새로운 객체의 주소 값(@8001~ ?)를 참조한다. 참조형 타입은 할당될때마다 메모리 상에서 새로 만들어 진다고 보면 된다. 이는 원본 데이터를 손상 시키는 부작용을 피할 수 있는 중요한 포인트이다.
정리
자바스크립트에서 데이터의 불변성과 가변성은 메모리 상에서의 성질을 얘기하는 것이며, 원시형 타입은 불변성을 띄고, 참조형 타입은 가변성을 띈다.
참고 자료:
- 코어 자바스크립트(정재남)
- Primitive vs. Reference Types: A JavaScript Guide