var, let, const
모두 변수를 선언하는 키워드이다.
let과 const는 ES2015(ES6)에서 등장했으며 여러가지 다른 특성을 갖는다.
var | let | const | |
유효 범위(스코프 범위) | Function Scope | Block Scope | Block Scope |
재할당 | 가능 | 가능 | 불가능 |
재선언 | 가능 | 불가능 | 불가능 |
1. 스코프 규칙
스코프에 관한 글
var는 함수 스코프를 갖는다.
하지만, let과 const는 블록 스코프를 갖는다.
1-1 var
var 키워드는 함수 스코프(Function Scope)이다.
이는 생성된 함수 스코프 내에서만 사용할 수 있으며, 외부에 선언된 경우는 전역 범위를 갖는다.
var age = 24;
function foo () {
var name = "JuHyeon"
var upAge = age + 1;
console.log(name); // JuHyeon
console.log(upAge); // 25
}
if(true){
var downAge = age - 1;
console.log(downAge); // 24
}
console.log(name); // Uncaught ReferenceError: name is not defined
console.log(upAge); // Uncaught ReferenceError: upAge is not defined
console.log(downAge); // 24
console.log(age); // 24
var키워드로 선언된 변수 name은 함수 외부에서 접근할 수 없다.
전역으로 선언된것이 아니기 때문에 foo 함수 스코프 내에서만 접근이 가능하다.
하지만, var키워드로 선언된 변수 downAge는 if문에서 중괄호('{}')내에 선언되어 있지만 if문 외부에서 사용이 가능한 모습을 보인다.
var키워드는 함수 스코프를 제외한 다른 스코프는 같은 스코프(전역 스코프)로 간주한다.
1-2 const와 let
let과 const 키워드는 블록 스코프를 갖는다.
블록이란? 여는 중괄호 { 와 닫는 중괄호 } 의 집합
즉, { 와 }의 사이의 공간을 의미.
블록 스코프를 정리한 글
var age = 24;
if(true){
let upAge = age + 1;
console.log(upAge); // 25
}
console.log(upAge); // Uncaught ReferenceError: upAge is not defined
var 키워드를 let 키워드로 대채해서 변수를 선언했다.
let 키워드로 선언된 upAge는 콘솔에서 에러를 발생한다.
왜 그럴까?
let과 const 키워드는 var 키워드와 달리 블록 스코프를 가지고있기 때문이다.
블록 내에서만 사용이 가능하기 때문에 블록 밖에서 사용하게되면 에러가 발생하는 것이다.
2. 호이스팅
호이스팅의 개념을 모른다면.... 호이스팅을 정리한 글을 보고오도록!!
Javascript는 모든 선언(var, let, const, function, class, 등)을 최상단으로 호이스팅 한다.
2-1 var
var 키워드는 함수 스코프 최상단으로 호이스팅 되고 선언과 동시에 undefined로 초기화된다.
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
위의 코드가 보여주듯 선언 하기 전에 출력하게되면 undefined가 출력되고 할당 후 할당한 값이 출력된다.
2-1 let, const
let과 const 키워드는 블록 스코프 최상단으로 호이스팅 되고 선언만 되고 값이 할당되기 전까지 어떤 값으로도 초기화가 되지 않는다.
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
let의 경우 선언 전에 호이스팅 되긴 하지만 어떤 값도 가지지 않기 때문에 ReferenceError가 발생한다.
이런 현상을 TDZ(Temporal Dead Zone) 라고 한다.
즉, 선언은 되었지만 참조는 할 수 없는 사각지대를 갖는 것이다.
3. 글로벌 객체로의 바인딩
strict mode가 아니라는 가정하에,
- var는 글로벌 스코프에서 선언되었을 경우 글로벌 객체에 바인딩된다.
- let과 const는 글로벌 스코프에서 선언되었을 경우 글로벌 객체에 바인딩되지 않는다.
var foo = "Foo"; // globally scoped
let bar = "Bar"; // globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
브라우저 환경에서 글로벌 객체는 window인데, var의 경우 바인딩되어 있고, let의 경우는 되어있지 않는다.
strict mode인 경우는 var와 let, const 모두 글로벌 객체에 바인딩되지 않는다.
4. 재할당
var와 let은 재항당이 가능하다.
하지만, const는 선언과 초기화가 반드시 동시에 일어나야 하므로 재할당이 불가능하다.
즉, 상수와 같은 고정값을 선언할 때 사용하는 키워드이다.
5. 재선언
var는 재선언이 가능하다.
하지만, let과 const는 재선언이 불가능하다.
var foo = "foo1";
var foo = "foo2"; // 문제없음
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
참고
- https://github.com/baeharam/Must-Know-About-Frontend/blob/main/Notes/javascript/var-let-const.md
- https://poiemaweb.com/es6-block-scope
- https://eun-ng.tistory.com/16
'JavaScript > Javascript' 카테고리의 다른 글
콜 스택(Call stack)과 힙(Heap) (0) | 2023.10.06 |
---|---|
IIFE (Immediately Invoked Function Expression, 즉시 실행 함수 표현식) (0) | 2023.10.04 |
네이티브 객체와 호스트 객체 (0) | 2023.09.26 |
클로저 Closure (1) | 2023.09.25 |
this 바인딩 (0) | 2023.09.22 |