변수(Variable)
-
변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙이 이름이다.
-
따라서 변수에 할당(assignmet)되는 것은 값(value)이다.
-
변수 이름을 JavaScript/식별자(Identifier)라고도 하며 식별자는 값이 아니라 메모리 주소를 기억하고 있다.
-
식별자로 값을 구별해서 식별한다는 것은 식별자가 기억하고 있는 메로리 주소를 통해 메모리 공간에 저장된 값에 접근할 수 있다는 의미이다.
-
ES6에서 let, const가 도입되기 전까지는 var 키워드(Keyword)로만 유일하게 변수를 선언할 수 있었다.
자바스크립트 엔진의 변수 선언 단계
- 자바스크립트의 인터프리터는 변수 생성의 선언 단계 및 할당 단계를 분할한다.
- 선언 부분은 코드가 실행되기 전에 현재 범위의 맨 위로 호이스팅(variable hoisting)되고 초기에 undefined 값이 할당된다.
- 즉, var의 경우, 초기화되기 전의 변수를 사용할 수 있다.
- let과 const의 경우는 undefined을 자체를 할당해주지 않기 때문에 에러가 난다.
1. 선언 단계
- 변수 이름을 등록해서 자바스크립트 변수의 존재를 알린다.
2. 초기화 단계
- 값을 저장하기 위한 메모리 공간을 확보하고 var의 경우 암묵적으로 undefined를 할당해 초기화(initialization)한다.
TDZ(Temporal Dead Zone)
-
let, const의 경우 호이스팅은 되지만 변수는 초기에 undefined로 초기화된 var와 달리 초기에 초기화되지 않는다.
-
코드가 실행되면 변수에 값을 할당하기 전에 콘솔 로그(에러)가 발생하므로 오류가 발생한다.
-
이러한 현상을 Temporal Dead Zone이라고 하며 변수를 사용할 수 없는 일시적 비활성 상태를 나타낸다.
변수 이름의 등록위치
- 변수 이름을 비롯한 모든 식별자(Identifier)는 실행 컨텍스트(execution context)에 등록된다.
- 변수 이름과 변수 값은 실행 컨텍스트 내에 키(key):값(value) 형식인 객체(Object)로 등록되어 관리된다.
ReferenceError
- 변수를 사용하려면 반드시 선언이 필요하다.
- 변수 뿐만 아니라 모든 식별자(함수, 클래스 등)도 그렇다.
- 만약 선언하지 않은 식별자에 접근하면 ReferenceError(참조 에러)가 난다.
변수 선언의 시점과 변수 호이스팅(variable hoisting)
JavaScript
-
위의 경우 변수 선언문보다 변수 참조하는 코드가 앞에 있다.
-
자바스크립트 코드는 인터프리터에 의해 한줄씩 순차적으로 실행되므로 console.log(score); 가 먼저 실행되고 var score;가 실행되기 때문에 참조에러가 발생할 것처럼 보이지만 var의 경우 선언과 동시에 undefined로 초기화가 되기 때문에 에러가 발생하지 않고 undefined가 출력된다.
-
그 이유는 즉 런타임(runtime)이 아니라 그 이전 단계에서 먼저 실행되기 때문이다.
-
자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 하고, 소스코드의 평가 과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.