본문 바로가기
필수 개발지식/JS

[JS] 자바스크립트(JavaScript)의 호이스팅(Hoisting)이란 무엇인가, var, let, const의 개념까지 쉽게 이해하기

by 코딩하는짱구 2023. 8. 1.
반응형

✅호이스팅(Hoisting)

  • 정의 : 자바스크립트에서 변수와 함수 선언이 해당 스코프의 최상단으로 끌어올려지는 동작
  • 자바스크립트 엔진은 코드를 실행하기 전에 첫번째 선언(Declaration), 두번째 실행(Execution)단계로 나뉜다.

 

ex)

1.변수 호이스팅

다른 언어에서라면 x 자체가 뜨지 않고 에러가 발생해야 하지만 JS에선 아니다.

변수 x가 선언되었지만 첫번째 줄에선 5가 할당되기전이기 때문에 undefinde 반환 

console.log(x); // undefined
var x = 5;

즉 실제로는 아래와 같은 순서로 동작하는 것이다.

var x; // 선언 단계가 끌어올려집니다.
console.log(x); // undefined
x = 5; // 초기화 단계

 

같은 이치로 아래의 결과값도 undefined, 1로 출력됌.

console.log(a)
a = 1
var a 
console.log(a)

 

 

2.함수 호이스팅

함수 선언문 전에 호출해도 정상적으로 동작한다.

foo(); // "Hello!"

function foo() {
  console.log("Hello!");
}

 

 

 

 

 

✅var, let, const

👉위에서 볼 수 있듯 var는 전역변수, 지역변수와 개념이 확실치않다는 문제가 발생한다. 

 

아래에서 함수 밖에 있는 i는 밖에서 선언되지 않았기 때문에 에러가 나야 정상이지만

실제로 결과는 1,2,3,4,5가 나와버리는데, 이유는 var같은 경우에는 function만 지역변수로 호이스팅하고 

나머지는 전부 전역변수로 올려버리기 때문이다.

for(var i = 1; i<5; i++){
console.log(i)
}
console.log(i)

 

같은 예로 아래와 같이 변수의 이름이 중복되기까지한다. 이는 같은 주민등록번호의 인간이 두명이 있다는것..! amazing!

var a = 1
console.log(a)
var b = 2
console.log(b)

 

 

👉이런 문제를 해결하기 위해 ES6부터 추가된 블록스코프(Block scope)변수 선언 방식인 let이 도입된다. 

let으로 선언한 변수는 변수가 선언된 블록 내에서만 유효하며 값 변경이 가능, 재선언은 불가능하다. 

즉 아래를 실행할시 SyntaxError: Identifier 'a' has already been declared 에러가 뜬다.

let a = 1
console.log(a)
let a = 2
console.log(a)

즉 위의 for 문의 var를 let으로 바꾸면 결과는 아래와 같다.

for (let i = 1; i < 5; i++) {
  console.log(i);
}
console.log(i);

 

마찬가지로 아래와같이 var로 선언했을때 undefined, a로 출력되던 결과값이 

console.log(a)
var a = 1 
console.log(a)

 

아래와 같이 let으로 바꿔줬을 땐 ReferenceError: Cannot access 'a' before initialization 에러가 뜬다.

console.log(a)
let a = 1 
console.log(a)

 

👉이유는 let 도 호이스팅이 되지만 Temporal Death Zone(TDZ)라는 개념이 생겼고 a 선언문이 나오기 전에는 a에 접근을 할 수 없게 되는것이다! (일시적인 사각지대라고 생각하면 쉽다)

 

 

 

 

 

✅결론

var

  • ES5이전에 사용되었던 변수 
  • 함수 스코프를 갖고 있으며 블록내에서 선언해도 함수 스코프를 갖는다
  • 변수가 선언되기 전에 사용해도 에러가 발생하지 않고 undefined 로 초기화된다
  • 재선언이 가능하다

let

  • ES6(2015)에서 도입된 변수 선언 키워드
  • 블록 스코프를 갖고 있어서 블록내에서만 접근할 수 있다
  • 변수가 선언되기전에 사용하면 에러 발생
  • 재선언 불가

const

  • ES6(2015)에서 도입된 상수 선언 키워드
  • 블록 스코프를 갖고 있어서 블록내에서만 접근할 수 있다
  • 재선언 불가, 값을 한번만 할당할 수 있다
  • 선언과 동시에 값을 할당해야함

 

즉 아래와 같이 let은 초기값을 할당하지 않아도 되지만 const는 반드시 초기화가 필요하다는 것 ~~

let x
x = 10 

const y
y = 10 

//const y
      ^

SyntaxError: Missing initializer in const declaration

 

결론적으로 var는 ES6전에 사용되었으며 호이스팅으로 인한 문제가 있기 때문에 let 과 const를 사용하도록 하자~~

 

반응형