[JS] 호이스팅(hoisting)과 TDZ(Temporal DeadZone)

Seju·2023년 8월 9일
1

JavaScript

목록 보기
26/28

🛷 호이스팅(hoisting) 이란?


🛤️ 호이스팅의 정의

javascript에서 호이스팅이란, 변수의 선언 및 함수의 선언이 해당 스코프의 최상단으로 끌어 올려진 것과 같은 현상을 뜻한다.

  • let이나 const로 선언한 변수는 선언 전에 접근할 수 없다.
  • 그러나 var로 선언한 변수는 선언 전에도 접근할 수 있다

// var 키워드 사용

console.log(foo);// undefined
var foo = 123;

// let키워드 사용

console.log(foo); // ReferenceError
let foo = 123;

위 코드의 결과를 보고 letconst는 호이스팅이 적용되지 않는다 는 오해가 생길 수 있다

  • 그러나, letconstvar와 같이 호이스팅된다. 그러나 호이스팅 되는 방식은 var 변수와의 차이점이 존재한다.
console.log(x) // Reference Error
console.log(y) // Reference Error

let x = 1;
const y = 1
  • 위 코드에서 콘솔에서 xy를 초기화하기 전에 접근하려고 하면 TDZ라는 영역에 있어 Reference Error가 발생한다
  • 이는 let이나 const로 선언한 변수도 호이스팅으로 인하여 변수가 존재하지만 초기화가 되지않아 접근할 수 없다는것을 의미한다

💀 TDZ(Temporal DeadZone)


모든 선언(=함수선언문,var,let,const,class)는 호이스팅되며,
varundefined로 초기화 되지만 letconst는 초기화 되지않은 Temporal DeadZone 상태로 유지된다

🤓 자바스크립트에서의 변수 생성 단계


  1. 선언 단계 (호이스팅이 일어나는 단계)

    • 변수의 식별자가 스코프에 등록
    • 변수에 대한 메모리 공간이 확보되고, 변수의 식별자로 스코프에서 접근이 가능해진다.
  2. 초기화 단계

    • 변수는 선언된 스코프에서 undefined로 초기화된다.
  3. 할당 단계

    • 변수에 실제 값이 할당되는 단계 변수의 값이 할당되거나 업데이트된다.

🫡 varlet/const의 호이스팅 시 차이점

var로 선언된 변수는 선언과 동시에 초기화가 이루어지는 반면
letconst로 선언된 변수는 선언 단계까지만 호이스팅 된다

  • 선언단계에서 varlet/const

    • var : 변수 식별자가 스코프에 등록되고 메모리 공간에 할당(호이스팅 발생)
    • let/const : 변수 식별자가 스코프에 등록되고 메모리 공간에 할당(호이스팅 발생)
  • 초기화단계에서 varlet/const

    • var : 변수가 undefined로 초기화된다 (이후 할당전까지 유지)
    • let/const : 변수는 초기화되지 않은 상태로 TDZ(할당 되기전까지의 임시적 사각지대)에 놓여있다

🪦 Temporal DeadZone

  • 임시적 사각지대(TDZ)는 letconst로 선언된 변수가 스코프에서 호이스팅 되었지만, 초기화 되기 전까지는 엑세스 할 수 없는 상태를 나타낸다.
  • TDZ에서 변수를 참조하려고하면 아래코드와 같이 참조에러가 발생한다.
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 26;

참조에러가 발생한이유는?

  • let으로 선언한 age가 호이스팅 되었지만 초기화 되지 않았기 때문이다.
  • TDZ는 변수의 일시적인 제약으로서, 변수가 실제 선언된 위치 이전에 사용되는것을 방지하는 효과가 있다.

TDZ가 끝나는 시점은?

  • 변수가 선언과 동시에 초기화되는 시점
    • 변수를 할당하는 단계도 해당 초기화 단계에 포함된다.
let x; // 선언 단계
x = 10; // 할당 단계 (동시에 변수의 초기화도 이루어진다.)
  • 아래 코드를 보았을때, let x= 10이전에 x 변수를 참조하려고하면 TDZ에 해당하는 부분에서 참조에러가 발생한다
  • 그러나 아래에선 변수 x가 선언되고 10으로 값이 할당되고 초기화된 이후에는 TDZ에서 벗어나 정상적으로 변수를 참조할 수 있다
function example() {
  console.log(x); // ReferenceError: Cannot access 'x' before initialization
  let x = 10;
  console.log(x); // 10 정상적으로 참조가능!
}

example();
profile
Talk is cheap. Show me the code.

0개의 댓글