ES5부터 변수를 선언할 수 있는 방법은 자료형에 상관없이 var로 통일해서 사용합니다.
다음 코드를 보겠습니다.
var ex=123;
console.log(ex);//123
{
var ex=456;
}
console.log(ex);//456
ex라는 변수가 전역 변수에서 초기화 된 후에 지역 변수로 선언하게 되면 전역변수(ex)가 지역변수의 값(456)을 가리킵니다.
그 이유는 자바스크립트는 함수 레벨 스코프를 따르기 때문이다.
더보기
함수 레벨 스코프(Function-level scope)
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다. 즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수이다.
블록 레벨 스코프(Block-level scope)
모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수이다.
javascript에서 변수가 선언되는 과정을 보겠습니다.
1. 자바스크립트는 실행시점에 변수와 함수에 대해 호이스팅을 수행.
*hoisting:변수와 함수를 소스의 맨 위에 위치시킴.
2.변수를 실행컨텍스트의 변수객체에 등록한다.
3.실행컨텍스트에 등록된 변수객체를 메모리에 할당한다. 이 단계에서 변수는 undefined로 초기화 된다.
4.undefined로 초기화 된 변수에 값을 할당한다.
ES6부터 도입된 let,const를 사용한 코드를 보겠습니다.
let ex=123;
let ex = 456; // Uncaught SyntaxError: Identifier 'ex' has already been declared
console.log(ex);//123
{
let ex=456;
console.log(ex);//456
}
console.log(ex);//123
var와 다른점 첫번째는 중복 선언이 안됩니다.
두번째는 블록 레벨 스코프를 따른다는 것입니다.
let,const가 선언된 범위 안에서 호이스팅 되고, 전역변수인 경우에는 코드 맨 위에서 호이스팅 됩니다.
console.log(ex); //undefined
var ex=123;
let exlet=123;
{
console.log(exlet);
let exlet=123; // ReferenceError: exlet is not defined
}
let의 변수 선언 과정은 다음과 같습니다.
1. 자바스크립트는 실행시점에 변수와 함수에 대해 호이스팅을 수행.
*hoisting:변수와 함수를 소스의 맨 위에 위치시킴.
2.변수를 실행컨텍스트의 변수객체에 등록한다.
3.스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다. 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)’라고 부른다.
4.실행컨텍스트에 등록된 변수객체를 메모리에 할당한다. 이 단계에서 변수는 undefined로 초기화 된다.
5.undefined로 초기화 된 변수에 값을 할당한다.
변수가 메모리에 할당 되기 전이기 때문에 참조할 수 없다는 에러를 겪게됩니다.
Reference
https://poiemaweb.com/es6-block-scope