하나의 값을 저장하기 위해 확보한 메모리 공간 자체 혹은 그 메모리 공간을 식별하기 위해 붙인 이름
let
const
var
변수가 생성되는 과정은 선언, 초기화, 할당. 총 3단계를 거쳐 진행 된다.
변수 선언 단계에서는 값을 저장하기 위한 메모리 공간을 확보하고
저장한 메모리를 식별하기 위한 변수 이름을 설정한다.
해당하는 메모리 공간에 undefined
를 할당하여 초기화한다.
undefined
로 초기화된 변수에 실제 값을 할당한다.
var
선언과 초기화가 동시에 된다.
(1) 선언 및 초기화 단계
(2) 할당단계
let
선언, 초기화, 할당 단계가 분리되어서 진행된다.
(1) 선언 단계
(2) 초기화 단계
(3) 할당 단계
const
선언과 할당이 동시에 진행된다.
(1) 선언 + 초기화 + 할당
// (X) const height; // SyntaxError height = 167; // (O) const height = 167;
식별자(변수명, 클래스명, 함수명 등)의 유효 범위를 의미한다.
스코프는 크게 전역 스코프와 지역 스코프로 나뉘는데
- 전역 스코프 : 어디에서든 접근 가능
- 지역 스코프: 한정된 범위에서만 접근 가능. 함수 스코프와 블록 스코프가 있다.
var
함수 스코프 (function-scoped)
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다.
즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다.
let
,const
블록 스코프 (block-scoped)
모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다.
즉, 코드 블록 내부에서 선언한 변수는 지역 변수이다.
호이스팅이란 변수나 함수의 선언이 해당 스코프의 최상위로 끌어올려지는 동작을 의미한다.
console.log(name); // undefined
var name = 'June';
호이스팅 때문에 변수를 선언하기 전에 name을 사용해도 에러가 생기지 않는다.
하지만 결과로 undefined
가 나오는 이유는
선언은 호이스팅 되지만 할당은 호이스팅 되지 않기 때문이다.
위의 예제는 아래와 같이 name이라는 변수 선언만 최상단으로 올려지고 'June' 이라는 할당은 아래에 그대로 있게 된다.
var name;
console.log(name); // undefined
name = 'June';
같은 코드를 let
을 사용하게 되면 ReferenceError 가 생긴다.
console.log(name); // ReferenceError
var name = 'June';
let
과 const
또한 호이스팅이 되지만 TDZ의 영향으로 변수 선언 전에는 변수를 사옹할 수 없다.
TDZ (Temporal Dead Zone)
일시적 사각지대라고도 불리는 이 영역은 스코프 시작지점부터 초기화 시작지점까지의 사각지대 구간이다.
선언 전에 변수에 접근하는 것을 금지한다.
var
를 사용하지 않는 이유변수를 중복 선언이 가능하다.
/* var */ var name = 'June'; console.log(name); // June var name = 'Ruby'; console.log(name); // Ruby /* let */ let name = 'June'; console.log(name); // June var name = 'Ruby'; // ERROR console.log(name);
함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역 변수가 된다.
변수 선언문 이전에 변수를 참조하면 언제나 undefined를 반환한다.
위의 이유로 vart
를 사용하면 예기치 못한 값이 반환될 수 있기 때문에 let
과 const
의 사용을 권장한다.