이 글의 '모던 자바스크립트 DeepDive'를 인용하여 작성되었습니다.
컴퓨터는 CPU를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다.
하지만, 자바스크립트는 개발자가 메모리 주소를 통해 값에 직접 접근하는 것을 허용하지 않으며, 값이 저장될 메모리 주소는 코드가 실행될 때 메모리 상황에 따라 임의로 결정된다. 이러한 이유로 프로그래밍 언어는 변수라는 메커니즘을 제공해 기억하고 싶은 값을 메모리에 저장, 저장된 값을 읽어 들여 재사용 할 수 있도록 한다.
식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름으로 변수 이름을 식별자라고도 한다. 식별자는 메모리 공간에 저장된 어떤 값을 식별해내기 위해 메모리 주소를 기억해야 한다.
즉, 식별자는 값이 저장되어 있는 메모리 주소와 매핑 관계를 맺으며, 이 매핑 정보도 메모리에 저장된다. 다시 얘기해, 식별자는 값이 아니라 메모리 주소를 기억하고 있다.(식별자는 메모리 주소에 붙인 이름이나 마찬가지이다.)
변수, 함수, 클래스 등은 전부 식별자로, 메모리 상에 존재하는 어떤 값을 식별할 수 있는 이름은 전부 식별자이다.
변수 선언이란 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해 값을 저장할 수 있도록 하는 것(=변수를 생성)이다. 자바스크립트 엔진은 변수 선언을 2단계에 걸쳐서 수행한다.
var score;
var 키워드로 선언한 변수는 어떤 값을 할당하지 않아도 undefined라는 값을 갖는다. 초기화 단계를 거치지 않으면 이전에 다른 애플리케이션이 사용했던 값이 남아 있을 수 있기 때문에, 값을 할당하지 않아도 undefined로 초기화를 수행해 이런 위험으로부터 안전하도록 한다.
자바스크립트 엔진은 소스코드 실행에 앞서 소스코드 평가 과정을 거친다. 이 평가 과정에서 자바스크립트 엔진은 모든 선언문을 찾아내어 먼저 실행한다. 따라서 소스코드 내 변수 선언 위치에 상관없이 어디서든 변수를 참조할 수 있다.
console.log(score); // undefined
var score;
자바스크립트 엔진은 변수 선언과 값의 할당을 하나의 문으로 단축 표현해도 변수 선언과 값의 할당을 2개의 문으로 나누어 각각 실행한다. 이 때, 변수 선언은 런타임 이전에 실행되고 값의 할당은 런타임에 실행된다.
console.log(score); // undefined
var score = 80;
console.log(score); // 80
var score = 80;
score = 90;