본문 바로가기
> 개발/Javascript

[Javascript] 변수의 정의와 선언, 할당

by @일리 2023. 2. 22.

모던 Deep Dive를 정독하면서 정리한 개념을 블로그에 올린다. 개발 공부를 막 시작했을 땐 이 책을 보고 좌절했었는데, 개발 공부를 어느 정도하고서 책을 다시 보니 내용이 어느 정도 이해가 된다. 내가 미처 몰랐던 부분들도 꽤 있어서 그 부분을 중점으로 정리해볼 예정이다. 혹시 잘못된 정보가 있으면 지적 부탁드립니다! 😅


변수의 정의

변수란 무엇일까? 내가 처음 자바스크립트를 공부할 때 배웠던 변수의 정의는 '데이터를 담는 공간'이었다. 상자는 변수이고, 그 상자 안에 값이 들어갈 수 있다는 간략한 설명을 들었던 게 기억이 난다. 그때 들었던 정의보다 좀더 디테일한 변수의 정의는 '하나의 값을 저장하기 위해 확보한 메모리 공간 그 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름'이다. 

 

변수가 필요한 이유는 무엇일까? 사람이 뇌에 기억을 저장하는 것처럼 컴퓨터는 메모리에 데이터를 저장한다. 메모리는 셀의 집합체로 각 셀은 고유한 메모리 주소를 가지고 있다. 변수는 컴퓨터가 기억하고 싶은 값을 메모리에 저장하고, 그 저장된 값을 읽어 가져올 수 있도록 하기 위해 필요하다.

 

예를 들어 10 + 20 이라는 연산을 통해 30이라는 값을 얻었다. 이 30은 메모리 공간에 저장이 된다. 나중에 이 30을 불러오기 위해서는 값이 저장된 공간의 위치를 기억해야 하는데, 저 공간을 기억해 참조할 수 있도록 공간에 상징적인 이름을 붙이는 것이 변수이다. 우리가 흔히 let apple;이라고 선언할 때 apple을 변수라고 부르는데 apple 은 변수의 이름(변수명) 혹은 식별자이다. 식별자는 '어떤 값을 구별해서 식별할 수 있는 고유한 이름'을 의미한다.

변수의 선언과 키워드

1. 변수의 선언

변수를 활용하기 위해서는 변수의 선언과 할당을 알아야 한다. 먼저 변수의 선언은 '변수를 생성하는 것'이다. 변수 선언은 크게 2가지 단계를 가진다.

 

  1. 선언 단계 : 변수의 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알림  
  2. 초기화 단계 : 값을 저장하기 위해 확보된 메모리 공간에 undefined를 할당해 초기화함

 

초기화 단계가 필요한 이유는 다른 애플리케이션이 사용했던 값이 확보한 메모리 공간에 남아있을 수 있기 때문이다. 쓸데없이 남아있는 값을 쓰레기 값(garbage value)라고 한다. 변수 선언만 한 상태에서 이 변수를 참조했을 때 쓰레기 값이 나오는 일을 방지하도록 자바스크립트에서는 초기화를 수행한다.

 

 

선언과 관련된 에러가 있다. 바로 ReferenceError다. 이 에러는 선언하지 않은 식별자에 접근할 때 나오는 참조 에러다. 아직 aa라는 변수를 선언해주지 않은 상태에서 변수를 입력했기 때문에 생기는 오류이다. 이러한 오류가 생기면 내가 변수를 제대로 선언했는지, 변수 이름에 오탈자는 없는지 확인하자!

2. 선언 키워드

변수를 선언할 때 사용하는 키워드는 세 가지이다. var, let, const이다. 일단 간략히 세 키워드를 비교해보면 다음으로 요약할 수 있다.

  • var : 재선언, 재할당 가능
  • let : 재선언 불가, 재할당 가능
  • const : 재선언, 재할당 불가

var 키워드를 사용했을 때는 호이스팅이 문제가 되는데, 간단하게 deep dive에 써있는 내용만 정리해보면, 자바스크립트 엔진은 소스코드를 실행할 때 1. 소스코드 평가과정에서 모든 선언문(변수, 함수 선언문 등)을 찾아내 먼저 실행하고 2. 선언문을 제외한 소스코드를 한 줄씩 순차적으로 실행한다. 따라서 변수 선언의 위치가 어디든 다른 코드보다 먼저 실행되기 때문에 어디서나 변수를 참조할 수 있다. 이렇게 변수 선언문이 코드의 최상단으로 끌어올려진 것처럼 동작하는 것을 변수 호이스팅이라고 한다.

 

 

참고로 호이스팅은 var 키워드와 함수표현식에서만 발생하는 문제가 아니라, let, const, function, class 등 키워드를 사용해서 사용하는 모든 식별자는 호이스팅이 된다고 한다. 위의 예시에서 var 키워드를 사용했을 때 test가 선언되고 undefined로 초기화되어 console.log에 undefined가 찍히게 된다. let도 똑같이 호이스팅이 일어난다고 했는데 왜 let의 console.log는 ReferenceError가 뜰까? 그것은 TDZ라는 일시적 사각지대의 영향 때문이다. 여기서 더 깊게 들어가려면 내가 공부를 더 하고와야 하니 일단 이 글에서는 여기까지만 설명하겠다!

변수의 할당

'선언된 변수에 값을 대입'하는 것을 변수의 할당이라고 한다. fruits라는 변수가 var로 이미 선언되었다고 할 때, fruits = '사과'; 를 함으로써 fruits에 사과를 할당할 수 있다. 여기서 사용되는 '=' 기호는 할당 연산자로 수학 계산식에서의 1+2 = 3에서의 '='과 다르다.  재할당은 값이 이미 할당되어있는 변수에 새로운 값을 다시 할당하는 것이다. 선언할 때 사용한 키워드(var, let, const)에 따라 재할당이 가능할 때가 있고, 불가능할 때가 있다. 참고로 변수를 선언할 때 선언과 동시에 초기화로 변수 값이 undefined가 되기 때문에 변수에 값을 처음으로 할당하는 것도 재할당이다.

 

fruits에 사과 말고 딸기를 대입을 해보자. 이때 사과가 저장되어 있던 메모리 공간을 지우고 그 공간에 다시 딸기를 채우는 것이 아니라 사과는 그 공간에 냅두고 다른 공간을 확보에 그곳에 딸기를 저장하는 식으로 매커니즘이 작동된다. 그럼 저 사과가 저장되어있는 공간은 그대로 버려진 공간이 되는 걸까? 이렇게 불필요한 값들이 모인 공간은 나중에 가비지 콜렉터에 의해 메모리에서 자동 해제된다.


혼자 var, let, const를 사용해 변수 선언과 할당을 하다가 const 키워드를 사용할 때는 무조건 선언과 할당을 동시에 해야 한다는 걸 알았다. const 키워드는 재선언과 재할당이 불가능하다는 걸 개념적으로는 알고 있었지만 이렇게 const로 선언만 해본 적은 없어서 이런 에러가 뜨는 것을 처음 봐서 신기했다. 궁금해서 MDN 문서를 찾아보니 const 키워드는 선언과 동시에 초기값이 필요해서 항상 선언과 할당을 동시에 해야 한다고 한다. 앞으로도 글로만 보지말고 코드를 치면서 여러 에러를 만나봐야겠다!

댓글