💭 var, let, const 를 중복 선언 허용, 스코프, 호이스팅 관점에서 서로 비교해 보자.
중복 선언 허용
|
var |
let, const |
중복 선언 허용 |
O |
X |
- 한 스코프에서 같은 변수를 let이나 const로 두 번 선언하면 에러가 발생한다.
- var는 변수의 중복 선언을 허용하는데 var로 같은 변수를 여러번 중복으로 선언할 수 있다.
- 하지만 이미 선언된 변수에 var를 사용하면 두번째 선언문은 무시된다.
let user;
let user; // SyntaxError: 'user' has already been declared
var user = "Pete";
var user = "John"; // 이 "var"는 아무것도 하지 않는다(이전에 이미 선언됨).
// ...에러 또한 발생하지 않는다.
alert(user); // John
스코프
|
var |
let, const |
스코프 |
함수 스코프 |
블록 스코프 |
함수를 기준으로만 적용되는 스코프 |
{중괄호}로 감싸진 코드 블록을 기준으로 적용되는 스코프 |
var로 선언한 변수의 스코프는 함수 스코프이거나 전역 스코프이다. |
블록 기준으로 스코프가 생기지 않기 때문에 블록 밖에서 접근이 가능하다. |
{블록}을 감싸더라도 블록을 무시하기 때문에 블록 안에 작성해도 전역 변수가 된다. |
블록문 안에서 let이나 const를 사용 했다면 블록문안에서만 접근할 수 있다. |
코드 블록이 function 안에 있다면 var는 함수 레벨 변수가 된다. |
function sayHi() {
if (true) {
var phrase = "Hello";
}
alert(phrase); // 제대로 출력
}
sayHi();
alert(phrase); // Error: phrase is not defined
호이스팅
- let과 const로 선언한 변수는 선언되기 이전에 사용될 수 없다.
- 하지만 var 변수는 함수 스코프를 기준으로 선언되기 이전에도 변수에 접근이 가능하다.
- var 선언은 함수가 시작될 때 처리된다. 전역에서 선언한 변수라면 스크립트가 시작될 때 처리
- 함수 본문 내에서 var로 선언한 변수는 선언 위치와 상관없이 함수 본문이 시작되는 지점에서 정의된다.
function sayHi() {
phrase = "Hello";
alert(phrase);
var phrase;
}
sayHi();
function sayHi() {
var phrase;
phrase = "Hello";
alert(phrase);
}
sayHi();
var phrase가 위로 이동한것처럼 적용되서 위의 두 코드는 동일하게 작동한다.
var로 선언한 변수 호이스팅 |
const, let로 선언한 변수 호이스팅 |
변수가 호이스팅 될 때는 선언, 초기화만 된채로 호이스팅 되고 할당까지 호이스팅 되지 않기 때문이다. |
const와 let은 var의 모호하고 too much로 유연한 문제점을 보완하기 위해 등장한 개념인 만큼 const와 let으로 변수가 선언되기 이전 라인에 해당 변수를 출력하는 코드를 작성한 경우 참조 오류가 발생한다. |
하지만 오류가 발생했다고 해서 const와 let으로 선언한 변수는 호이스팅의 예외가 되는 것은 아니다.
여기서 TDZ(Temporal Dead Zone)에 대한 개념이 나온다. |