[Javascript] var, let, const 차이점과 호이스팅

ᴄsᴇ ᴘᴇʙʙʟᴇ·2024년 1월 14일
0

Javascript 공부 노트

목록 보기
2/5
post-custom-banner

범위(scope)

변수가 접근할 수 있는 유효범위이다.

1. function scope
var만의 특징. 유효범위가 함수 단위이다. 즉 함수에서만 지역변수가 된다.

const func = () => {
  var a = 1;
}
console.log(a); // 함수 안에서 선언된 변수 a를 함수 밖에서 접근했으므로 오류 발생! 

if(true) {
  var a = 1;
}
console.log(a); // if문에서 선언된 a를 if문 밖에서 접근. 문제 없음~

2. block scope
유효범위가 함수 뿐만 아니라 중괄호(함수, if-else문, while문, for문, try-catch문)를 기준으로 나뉘는 것. 변수는 중괄호를 범위로 기억한다는 점 인지하고 자바스크립트 코드를 짜자!

const func = () => {
  const a = 1;
}
console.log(a); // 함수 안에서 선언된 변수 a를 함수 밖에서 접근했으므로 오류 발생! 

if(true) {
  let a = 1;
}
console.log(a); // if문에서 선언된 a를 if문 밖에서 접근했으므로 오류 발생!

변수 재선언(redelcaration)

좋지 않은 var만의 특징이다.
말도 안되는 기능. 이런 선언 방식은 볼 일 없을 듯!

var name = "Mike";
console.log(name); // Mike

var name = "Jane"; // 변수 재선언. 오류가 발생하지 않는다.
console.log(name); // Jane 

변수값 재할당(can be reassigned)

당연한 변수의 특징.
constant는 상수니까 당연히 재할당이 안된다.

//var
var name = "Mike";
name = "Jane";
console.log(name); // Jane 

//let
let name = "Mike";
name = "Jane";
console.log(name); // Jane 

//const
const name = "Mike";
name = "Jane"; // const는 재할당 불가. 오류발생!

초기화 필요(initializer)

constant는 재할당이 안되니까 당연히 초기값을 설정해주어야 한다.

const name; // const는 초기값 설정 필수. 오류 발생!

호이스팅(hoisting)

호이스팅이란?

  • 호이스팅이란 스코프 안에 존재하는 모든 "선언"들을 해당 스코프의 최상단으로 끌어올리는 것을 말함. (호이스팅은 스코프 단위로 일어난다!)
  • 자바스크립트 엔진은 코드를 실행하기 전에 실행 가능한 코드를 형상화하고 구분하는 과정을 거침.
  • 이 과정에서 자바스크립트 엔진은 코드 실행을 위한 모든 선언들을 스코프에 등록(메모리에 저장)함.

var, let, const 모두 호이스팅된다. 하지만 차이점이 있다.

var 예시를 보자.

console.log(name); // undefined
var name = 'hello';

이 코드는 참조 에러가 나지 않고, undefined를 리턴한다. 그 이유는 자바스크립트가 호이스팅을 하면서 아래와 같은 방식으로 코드를 해석하기 때문이다.

var name; // undefined
console.log(name);
name = 'hello';

선언만 호이스팅되고, 할당은 호이스팅 되지 않은 것이다.

다음으로 let, const 예시를 보자.

console.log(name); // 에러 발생! 
let name = 'hello';
console.log(name); // 에러 발생! 
const name = 'hello';

분명 var 예시와 같은 코드인데, let이나 const으로 바꾸면 에러가 난다. 이것만 보면 letconst는 호이스팅이 일어나지 않는 것처럼 보인다.

하지만 둘다 분명히 호이스팅이 일어난다. 그럼 왜 이런 차이점이 발생할까? 바로 Temporal Dead Zone 때문이다.

Temporal Dead Zone
선언은 되었으나 초기화되지 않은 변수가 있는 곳을 Temporal Dead Zone이라고 한다. Temporal Dead Zone에 있는 변수에 접근하면 Reference Error가 발생한다.

var는 변수의 선언과 동시에 초기화가 일어난다. 선언을 하면 자동으로 undefined가 할당된다. 따라서 Temporal Dead Zone에 들어갈 일이 없다.

반면 letconst는 변수를 선언한다고 해서 자동으로 초기화가 이루어지지 않는다. 따라서 선언은 되어있지만, 초기화가 되지 않아 Temporal Dead Zone에 들어가게 된다.

예시들을 통해 이해하자.

// 호이스팅 때문에 선언이 끌어올려져서 오류 안남.
console.log(text); // undefined (선언+undefined로 자동 초기화)
text = 'Hi!'; // 할당
var text; // 선언과 동시에 초기화. 호이스팅됨.
console.log(text); // Hi!
// 호이스팅 때문에 선언이 끌어올려졌지만 초기화 안된 상태에서 참조해서 오류 남.
console.log(text); // ReferenceError: text is not defined
let text; // 선언되어 호이스팅. 초기화는 안됨

참조
https://yceffort.kr/2020/05/var-let-const-hoisting
https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/

profile
ꜱɪɴᴄᴇ 2021.09.01
post-custom-banner

0개의 댓글