✨ 변수의 종류
- let
- const
- var
var
는 한번 선언된 변수를 다시 선언할 수 있다.
// ✅
var name = 'Mike';
console.log(name); // Mike
var name = 'Jane';
console.log(name); // Jane
// ❌
let name = 'Mike';
console.log(name); // Mike
let name = 'Jane'; // error! (동일한 이름으로 재선언 불가)
console.log(name);
var
는 선언하기 전에 사용할 수 있다.
console.log(name); // undefined
var name = 'Mike';
위의 예제에서 에러가 발생하지 않는다. var
는 아래처럼 동작하기 때문이다.
var name;
console.log(name); // undefined
name = 'Mike'; // 할당
var
로 선언한 모든 변수는 코드가 실제 이동되지 않지만 최상위로 끌어 올려진 것처럼 동작한다. 이를 호이스팅이라고 한다. 해당 코드 실행 결과, 콘솔에는 undefined
가 찍힌다. 이는 선언은 호이스팅되지만 할당은 호이스팅되지 않았기 때문이다. 따라서 변수 선언만 최상단으로 올려진 것이고 할당은 해당 자리(세번째 줄)에서 처리된다.
호이스팅(Hoisting) : 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동
같은 상황에서 let
은 에러가 발생한다.
console.log(name); // ReferenceError
let name = 'Mike';
이는 Temporal Dead Zone, 이하 TDZ
영역에 있는 변수들은 사용할 수 없기 때문이다. TDZ
는 선언이 호이스팅 되더라도 초기화(초기 할당)가 이루어지기 전까지는 해당 변수에 접근할 수 없는 구역을 지칭한다.
Tmporal Dead Zone(TDZ): 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 말한다.
/** Temporal Dead Zone **/
console.log(name); // 선언만 호이스팅되고 초기화는 x
/** Temporal Dead Zone **/
const name = 'Mike'; // 함수 선언(호이스팅 됨) 및 초기화
console.log(name); // 사용 가능
let
과 const
는 TDZ
의 영향을 받는다. 즉, 초기화 이전까지 해당 변수에 접근할 수 없다. 이를 통해 코드를 예측 가능하게 만들고 잠재적인 버그를 줄일 수 있다.
// ✅
let age = 30;
function showAge() {
console.log(age);
}
showAge();
// ❌
let age = 30;
function showAge() {// function scope
/** Temporal Dead Zone **/
console.log(age);
/** Temporal Dead Zone **/
let age = 20;
} // function scope
showAge();
호이스팅은 스코프 단위로 일어난다. 여기서 스코프scope
는 function 함수 내부이다. TDZ
가 존재하는 두번째 경우를 살펴보자.
let
으로 선언한 두번째 age변수가 호이스팅을 일으킨다.- 따라서 초기화가 아직 이루어지지 않은, 콘솔로 출력하는 부분에서
RefferenceError
가 발생한다. - 만약 호이스팅이 일어나지 않았다면 함수 바깥에서 선언한 age가 30으로 출력될 것이다.
✨ 변수 생성 과정
변수는 3단계의 생성과정을 거친다
- 선언
- 초기화
- 할당
var
- 선언 및 초기화 단계 (초기화:
undefined
를 할당해주는 단계) - 할당 단계
var
는 선언과 동시에 초기화된다. 따라서 할당 전에 호출하면 에러를 내지 않고undefined
를 반환한다.
let
- 선언 단계
- 초기화 단계
- 할당 단계
let
은 초기화 단계와 선언 단계가 분리돼서 이루어진다. 호이스팅되면서 선언 단계가 이루어지지만 초기화단계는 실제 코드에 도달했을 때 발생하므로ReferenceError
가 발생한다.
const
- 선언 + 초기화 + 할당
선언과 할당이 동시에 이루어진다. 따라서 const
는 값 변경이 불가능하다.
✨ 스코프
var
: 함수 스코프(function-scoped)let
,const
: 블록 스코프(block-scoped)
블록 스코프는 모든 코드 블록에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 외부에서 접근할 수 없다. 즉, 코드 내부에서 선언한 변수는 지역변수이다. 여기서의 코드 블럭은 함수, if 문, for 문, while 문, try/catch 문 등을 말한다.
function add() {
// Block-level Scope
}
if() {
// Block-level Scope
}
for(let i=0;i<10;i++) {
// Block-level Scope
}
반면, 함수 스코프는 함수 내에서 선언된 변수만 그 지역 변수화 된다. 예를 들어 if문 내에서 선언한 변수는 구문 밖에서도 사용이 가능하다. 하지만 let
과 const
는 블록 스코프이기 때문에 중괄호를 벗어나는 순간 사용이 불가능하다.
const age = 30;
if(age>19) {
var txt = '성인';
}
console.log(txt); // '성인'
var
도 함수 내부에서 선언되면 함수 외부에서 사용이 불가능하다. 유일하게 벗어날 수 없는 스코프가 함수라고 생각하면 된다.
function add(num1, num2) {
var result = num1 + num2;
}
console.log(result); // ReferenceError
참고: 자바스크립트 중급 강좌 #1 - 변수, 호이스팅, TDZ(Temporal Dead Zone)
'Frontend' 카테고리의 다른 글
React-Query 정리 (0) | 2022.08.05 |
---|---|
[Javascript] Throttle 과 Debounce (0) | 2022.05.12 |
[Redux] 간단한 예제로 살펴보는 리덕스의 동작 원리 (0) | 2022.03.17 |
[React] ContextAPI & useContext Hook을 통한 Global State 값 관리하기 (0) | 2022.03.11 |
[Typescript] Advanced-Types & Utility-Types 정리 (0) | 2022.03.02 |