변수 선언
변수를 사용하기 위해서는 가장 먼저 변수를 선언해야 한다. 변수의 선언은 어떤 값의 주소를 담기 위한 메모리 공간을 확보하고 이름을 붙이는 것이다. 자바스크립트에서는 var
, let
, const
키워드를 사용해 아래와 같이 변수를 선언할 수 있다.
var name;
명심해야할 점은 변수에 값 자체를 담는 것이 아닌, 해당 값이 담겨있는 주소를 담는 다는 점이다. C언어의 포인터를 생각하면 이해가 쉽다. 변수에 매번 새로운 값을 할당 하면, 그때마다 변수는 그 새로운 값의 메모리를 가르킨다.
초기화
변수를 선언했으면 이제 값을 할당해야 할테지만, 자바스크립트에서는 값을 할당하지 않은 변수(단, const
로 선언한 변수는 제외)를 사용해도 에러가 발생하지 않는다. 값을 할당하지 않은 위의 변수 name
을 출력해 이를 확인해보면 undefined
가 출력되는 것을 확인할 수 있다.
console.log(name); //undefined
이는 자바스크립트의 변수 선언에서의 독특한 특징 때문이다. 선언된 변수는 어떠한 값도 가르키고 있지 않을 것 같지만, 사실 자바스크립트 엔진은 변수가 선언됨과 동시에 암묵적으로 undefined
를 할당해 초기화 한다. undefined
가 할당되는 과정까지가 자바스크립트 선언의 한 단계인 것이다.
만약 아래와 같이 "jaesoek"이라는 값을 선언과 동시에 할당해도, 이는 실제로는 두 단계로 나누어 실행된다.
var name = 'jaesoek';
- 선언:
name
의 메모리 공간을 확보하고undefined
를 할당 - 할당:
name
에 문자열 "jaesoek"이 담긴 메모리 주소를 재할당
내부적으로 name은 먼저 undefined로 초기화된 뒤 "jaesoek"이 재할당되는 것이다.
변수 호이스팅
console.log(foo) //(a)
var foo = 10;
console.log(foo) //(b)
만약 위 코드를 실행하면 어떤 결과가 출력될까? 답을 알기 위해서는 먼저 호이스팅이 무엇인지 알아야 한다.자바스크립트 엔진은 소스코드를 실행하기 전, 코드를 평가하는 과정에서 여러가지 일을 수행한다. 이때 변수를 포함한 함수, 클래스 등의 선언문들을 찾아 미리 실행하는데, 이를 호이스팅이라고 한다.
위 코드의 2번째 줄에서 선언은 var foo;
까지이다. 여기까지는 소스코드가 실행되기 이전에 실행되므로 (a)에는 undefined
가 출력될 것이다. 그리고 다시 두 번째 줄에서 foo = 10;
으로 재할당되면 (b)에서는 10이 출력된다.
TDZ(Temporal Dead Zone)
let
, const
키워드를 사용해 선언한 변수는 어떨까?
console.log(bar);
const bar = 20; //ReferenceError: Cannot access 'bar' before initialization
초기화 전에 bar
에 접근할 수 없다는 에러가 발생한다. 그럼 let
과 const
는 호이스팅이 일어나지 않는 걸까? 그렇지 않다. 이들도 분명 호이스팅이 발생하지만, var
키워드와 한 가지 다른 점은 선언과 초기화 과정 사이에 하나의 구간이 더 존재한다는 것이다. 그것이 바로 TDZ 즉, 일시적 사각지대인데, 이 구간에 있는 변수에 접근하려 하면 위와 같이 ReferenceError가 발생한다.
TDZ는 호이스팅으로 인해 생길 수 있는 의도치 않은 동작들을 막아줄 수 있다. 따라서 변수 선언시 var
의 사용은 최대한 지양하고 let
과 const
를 사용하는 편이 좋다. 호이스팅 외에도 var
키워드를 사용해선 안되는 이유들이 있지만 이것은 이후 포스팅에서 더 자세히 다뤄보도록 하겠다.
참고자료
- 모던 자바스크립트 Deep Dive - 이웅모
'Javascript' 카테고리의 다른 글
[Javascript] 리덕스 만들어보기 - (1) (0) | 2022.07.24 |
---|---|
[Javascript] this: 이름 값 못하는 자바스크립트의 this (0) | 2022.07.03 |
[Javascript] requestAnimationFrame(애니메이션 최적화하기) (0) | 2022.04.25 |
[Javascript] Closure (0) | 2022.04.14 |
[Javascript] Tagged Templates (styled-components의 이상한 문법) (1) | 2022.02.25 |
댓글