JavaScript - 호이스팅(hoisting)

Big Jay·2022년 8월 13일
0

JavaScript

목록 보기
5/8

해당 내용은 자바스크립트의 동작 원리에 대하 알고 읽으면 이해가 좀 더 수월합니다.

자바스크립트 - 실행 컨텍스트

호이스팅

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미 - 출처: mdn web docs

호이스팅은 마치 코드 자체를 스코프의 상단으로 끌어올려 먼저 실행하는 것 처럼 느끼게 한다.

호이스팅은 모든 선언문에 대해서 발생한다.

  • 변수 선언문(var, let, const)
  • 함수 선언문(function)
  • class

다만 모든 것이 스코프 상단으로 끌어올려진것 처럼 작동하진 않는다.

console.log(name) // undefined
sum(1,2) // 3
console.log(number) // Reference Error
console.log(age) // Reference Error
var name = "Jay";
function sum(a, b){
  console.log(a+b)
}
let number = 10;
const age = 18;

let과 const는 var, function 선언문과 다르게 오류가 나타난다.

같은 변수 선언문인데 다른 이유?

변수의 생성 단계는 총 3가지로 구분된다.
1. 선언 단계(Declaration phase)
전역 객체에 변수를 등록하며, 스코프가 참조할 수 있는 대상이 된다.
2. 초기화 단계(Initialization phase)
전역 객체에 등록된 변수를 메모리에 할당하며, 값을 undefined로 초기화 한다.
3. 할당 단계(Assignment phase)
실제 변수에 실제값을 할당한다.

  • var은 자바스크립트 엔진이 코드 평가하는 단계에서 선언 단계초기화 단계가 동시에 이루어진다. 그렇기 때문에 코드를 실제 실행하기 전부터 참조가 가능한 것

  • let은 선언 단계초기화 단계가 분리되어 진행되며, 코드 실행 단계에서 선언문을 읽기 전까진 참조할 수 없다. 이는 일시적 사각지대(TDZ)에 빠진다.

  • const는 한가지를 제외하고는 let과 동일하게 작동한다. const는 초기화와 할당 단계가 동시에 진행된다.

함수 선언문은 평가되면서 함수 이름과 동일한 이름의 식별자를 전역객체에 키로 등록하고 생성된 함수 객체를 즉시 할당한다.

TDZ

TDZ(Temporal Dead Zone) 일시적 사각지대 라는 뜻으로 변수가 스코프의 시작 지점부터 초기화 단계 시작 지점까지 변수를 참조할 수 없다.

// var 키워드로 선언한 변수는 런타임 이전에 선언 단계와 초기화 단계가 동시 실행된다.
// 그렇기 떄문에 변수 선언문 이전에 변수를 참조 할수 있다.
console.log(foo); // undefined

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

// 할당 단계
foo = 1;
console.log(foo); // 1

TDZ는 var 변수 선언문에는 적용되지 않으며, let과 const는 작동한다.

// 런타임 이전에 선언 단계가 실행(초기화는 X)
// TDZ로 인해 변수가 선언 전에는 참조 불가
console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기 단계가 실행되어 TDZ에서 빠져나와 참조 가능해진다.
console.log(foo); // undefined

foo = 1;
console.log(foo); // 1

// 런타임 이전에 선언 단계가 실행(초기화는 X)
// TDZ로 인해 변수가 선언 전에는 참조 불가
console.log(foo); // ReferenceError: foo is not defined

const foo; // Uncaught SyntaxError: Missing initializer in const declaration
console.log(foo); // ReferenceError: foo is not defined

const foo = 1;
console.log(foo); // 1

참고

profile
안녕하세요.

0개의 댓글