본문 바로가기

JavaScript

깊게 들어가는 const

 

const.... 임마는 상수를 선언할 때 사용한다

상수는 변경되지 않는 값 이고 한번 어떤 값을 할당하면 다른 값 재할당이 불가능하다

 

CODE 1

const a = 1
a = 2

//TypeError: Assignment to constant variable.

 

그래서 위 코드를 보면 

  1. 첫번째 줄의 a에 값 1을 할당하였고
  2. 두번째 줄에서 값 2를 재할당하였다

a는 const로 선언되었기 때문에 당연히 타입에러가 난다

 

 

이번에는 이 코드를 봐보자

CODE 2

const obj1 = { a: 1, b: "abc" };

obj1.a = 2

//에러 없어요~~

 

CODE 1과 마찬가지로 const로 선언해 주었는데 다른 점은

CODE 1에서는 원시값을 할당 해 주었고

이번 코드에서는 객체,그러니까 참조값을 할당 해 주었다

 

 

얼레? 이번에는 에러가 안나네? const 잖아...

재할당이 이뤄졌는데도 왜 에러 안남..?

 

변수와 상수를 구분짓는 변경 가능성의 대상은 변수 영역 메모리입니다.
한번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부가 관건입니다.

-코어 자바스크립트 中

 

아래 표를 보면 위의 말이 이해가 될 것이다 (..아마도?)

 

code 2 메모리 할당 과정 1

변수영역 주소 1001 1002 1003 1004 1005
데이터   이름:obj1
:@5001
       
데이터
영역
주소 5001 5002 5003 5004 5005
데이터 @7103 ~ ?   1 ‘abc’    
@5001
변수영역
주소 7103 7104 7105 7106 7107
데이터 이름 : a
: @5005
이름:b
:@5004
       

 

  1. 변수 영역의 빈 공간 (@1002) 그 주소의 이름을 obj1로 지정
  2. 임의의 데이터 저장공간 (@5001)에 데이터 저장하려는데, 이 데이터는 여러 변수와 값들을 모아놓은 그룹(객체)이다 
    이 그룹의 각 변수(프로퍼티)들을 저장하기 위해 별도의 변수 영역 (@7103 ~ ?)을 마련하고 그 영역의 주소를 @5001에 저장
  3. @7103과 @7104에 각각 a와 b라는 프로퍼티 이름을 지정
  4. 데이터 영역에서 숫자 1을 검색하고 검색 결과가 없으므로 임의의 공간(@5003)에 숫자 1을 저장
  5. 마찬가지로 데이터 영역에서 문자열 'abc'를 검색하고 검색 결과 없으므로 임의의 공간 (@5004)에 문자열 'abc'를 저장
사실 변수영역과 데이터영역이라는 명칭은 없다고 하나 내가 참고한 책 '코어 자바스크립트'에서 이해를 쉽게 하기 위해 이렇게 이름을 붙였다고 한다.

 

여기까지가 CODE 2의 첫번째 줄에서 일어나는 일들 이다

 

이제 문제의 코드가 실행되었을 때의 과정을 알아보자

code 2 메모리 할당 과정 2

obj1.a = 2

 

변수영역 주소 1001 1002 1003 1004 1005
데이터   이름:obj1
:@5001
       
데이터
영역
주소 5001 5002 5003 5004 5005
데이터 @7103 ~ ?   1 ‘bbb’ 2  

 

@5001
변수영역
주소 7103 7104 7105 7106 7107
데이터 이름 : a
: @5005
이름:b
:@5004
       

 

  1. obj1의 a프로퍼티에 숫자 2를 할당하려고 한다
  2. 데이터 영역에서 숫자 2를 검색하고,검색 결과 없으므로 임의의 공간(@5005)에 숫자 2 저장하고 이 주소를 @7103에 저장

빨간색 배경으로 칠해진 셀을 보면 @7103의 값은 바뀌었지만 obj1의 값 @1002은 변하지 않았음을 확인 할 수 있다.

이처럼, obj1을 const로 선언했음에도 불구하고 obj1.a = 2 처럼 값을 재할당이 가능한 이유는 

obj1이 가지고 있는 주소값은 변함이 없기 때문이다

 

물론 ,

const obj1 = { a: 1, b: "abc" };

obj1 = { a: 23323 };

//TypeError: Assignment to constant variable.

 

위 코드처럼 아예 새로운 객체를 재할당 한다면 obj1이 가지고 있는 주소값 또한 바뀔 것 이므로 타입에러가 난다

 

 

그러면 이제 에러가 나던 CODE 1의 경우를 봐 보자

 

code 1 메모리 할당 과정 1 

const a = 1
변수영역 주소 1001 1002 1003 1004 1005
데이터   이름: a
:@5003
       
데이터
영역
주소 5001 5002 5003 5004 5005
데이터     1      
  1. 임의의 공간 (@1002)의 이름을 a로 지정
  2. 숫자 1 값을 검색, 검색결과 없으므로 임의의 공간 (@5003)에 숫자 1 값 저장하고 이 주소를 (@1002)에 저장

여기까지는 일반적인 값 할당 과정이므로 문제가 없다

 

code 1 메모리 할당 과정 2

a = 2
변수영역 주소 1001 1002 1003 1004 1005
데이터   이름: a
:@5004 (변했다)
       
데이터
영역
주소 5001 5002 5003 5004 5005
데이터     1  2    

 

  1. 숫자 2 값을 찾고 ,검색결과 없으므로 임의의 공간 (@5004)에 숫자 2 값 저장하고 이 값을 @1002에 저장

이처럼 @1002의 값이 @5004로 변한 것을 확인 할 수 있다

값이 변했으므로(재할당) 이것이 에러가 나는 이유이다.

 

메모리 할당 과정에서 알아보았듯이 원시형과 참조형은 서로 메모리 할당 과정이 다르기 때문에 이런 일이 발생한다

  • 원시형 : 주소값을 복사하는 과정이 한번만 일어남
  • 참조형 : 주소값을 복사하는 과정이 한단계를 더 거치게 됨

 

 코어 자바스크립트를 참고하여 작성하였습니다.

'JavaScript' 카테고리의 다른 글

자바스크립트 배열  (0) 2023.06.17
디바운스와 쓰로틀링  (0) 2023.06.16
[JS] var,let,const 의 차이  (0) 2023.02.18