[JS] var, let, const 차이점 | Hoisting | TDZ(Temperature Danger Zone)

insuzy·2021년 8월 10일

📌 let

let name = 'subin';
console.log(name);
// 'subin'
name = 'testUser';
console.log(name);
// 'testUser'
let name = 'name';
// Error SyntaxError: Identifier 'name' has already been declared
  • 변수를 만들 때 let 키워드 사용.
  • ES6에 추가됨
  • 재할당 가능, 재선언 불가능

📌 const

const test = 'test'; console.log(test); 
// test
test = 'test1'; 
console.log(test); 
// Error Assignment to constant variable.
const test = 'test'; console.log(test); 
// Error SyntaxError: Identifier 'name' has already been declared
  • 상수
  • 재선언, 재할당 불가능
  • 가독성, 유지보수를 위해 사용

📌 var

  • 재선언, 재할당 가능, 함수 스코프

🔗 Hoisting

console.log(age); // undefined
age = 27;
var age;
console.log(age); // 27
  • 변수 선언 끌어올림

var 키워드를 이용할 경우 변수의 선언을 항상 컨텍스트 내의 최상위로 끌어올린다.

이로인해 undefined 로 값이 초기화 되기 때문에, 선언하기 전에도 값을 사용할 수 있다.

호이스팅은 변수만 해당되는 것이 아니라, 함수도 가능하며 함수의 호출을 첫 줄에서 하고 마지막 줄에 함수를 정의해도 문제가 없다.

- 변수 선언의 3단계

  • 선언 → 초기화 → 할당
  • 선언 단계(Declaration phase) : 스코프에 변수를 등록
  • 초기화 단계(Initialization phase) : 메모리에 할당하고 이 단계에서 자동으로 undefined로 초기화
  • 할당 단계(Assignment phase) : 초기화된 변수에 값을 할당

- var hoisting

console.log(fruit); 
// undefined
var fruit;
fruit = 'apple';   
console.log(fruit);
// apple
  • var에서는 선언과 초기화(메모리 공간 확보)가 동시에 이루어짐.
  • 선언 및 초기화한 후 할당 단계 이전에는 undefined 값이 있으며 참조할 수 있다.

- let, const hoisting

그럼 과연 let과 const에서는 호이스팅이 안 될까? 🤨

아니다.. 된다!!! 🙆🏻‍♀️

console.log(fruit); 
// ReferenceError 선언문 이전에 참조 불가
// 1. 선언
let fruit;
console.log(fruit);
// undefined

// 2. 초기화
fruit = 'apple'; 
console.log(fruit);
// apple
  • var와 다르게 let은 선언 및 초기화 단계가 분할된다.
  • 실행 컨텍스트에 변수를 바인딩했지만, 메모리에 할당 되지 않아 ReferenceError 발생하므로, let과 const는 호이스팅이 안 된다고 오해하는 것이다!
  • 선언 단계 실행 후 선언문에 도달했을 때 초기화가 이루어진다.
  • 변수 선언문 이전에 참조 불가능하다.
  • let, const 선언은 TDZ에 의해 제약을 받는다.

▶ TDZ(Temperature Danger Zone)가 뭐야?

  • 스코프의 시작점부터 초기화 시작점까지의 구간이다.
  • 변수가 존재하지만 값을 할당할 때까지 참조할 수 없는 지점을 의미한다.

🔗 변수의 유효범위

- function-scope

  • 함수가 생성될 때 마다 새로운 스코프 발생
  • var는 함수 스코프이다.

▶ var의 경우

function num() {
	for(var i = 0; i < 5; i++) {
		console.log(i);
	}
	console.log('num : ', i);
}
num();
console.log(i);
/*
0
1 
2 
3 
4
num : 5
*/
// i is not defined

함수 스코프이므로 i 접근 불가능.

▶ let의 경우

function num() {
	for(let i = 0; i < 5; i++) {
		console.log(i);
	}
	console.log('num : ', i);
}
num();
console.log(i);

// Error ReferenceError: i is not defined

-외부에서 i 접근 불가능.

- block-scope

  • {} 블럭 단위 스코프
  • 블럭이 생성될 때마다 새로운 스코프 발생
  • {}, if, for, while, switch

▶ var의 경우

var score = 27;
if(score >= 19){
  var result = true;
}
console.log(result); 
// true
  • if문 내부의 result 변수가 전역변수로 선언됨.

▶ let의 경우

for(let i = 0; i < 3; i++){
  console.log(i); 
}
console.log(i); 
// Error i is not defined 
  • for 선언문에서 선언한 변수를 외부에서 참조 불가능!

👊🏻 결론, var 쓰지말자.

var 를 쓸 경우 호이스팅 문제가 있으며 변수 중복 선언이 가능하고 함수 이외에 변수는 전역 변수가 되므로 전역변수를 남발할 가능성이 매우 높다. 예측 불가능한 코드들.. var를 이제 더이상 놔주자.

출처
https://www.youtube.com/watch?v=OCCpGh4ujb8
https://onlydev.tistory.com/29
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let
https://www.w3schools.com/js/js_hoisting.asp
https://namu.wiki/w/%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85
https://medium.com/korbit-engineering/let%EA%B3%BC-const%EB%8A%94-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-%EB%90%A0%EA%B9%8C-72fcf2fac365
https://dmitripavlutin.com/variables-lifecycle-and-why-let-is-not-hoisted/
https://noogoonaa.tistory.com/78

profile
UI Developer. publisher

0개의 댓글