모래블로그

[JavaScript] 호이스팅이란 본문

Language/JavaScript

[JavaScript] 호이스팅이란

별모래 2024. 1. 19. 16:21
728x90

💡호이스팅

호이스팅(hoist)의 사전적 정의 : 끌어올리기

 

자바스크립트에서 호이스팅이란 ?

인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다.

함수 내 변수 및 함수 선언을 각 해당 스코프의 최상단으로 끌어올려주는 것이다. (물리적으로 코드가 옮겨지는 것은 X)

 

컴파일 단계에서 코드 실행 전 함수와 변수 선언을 스캔하고, 모든 함수와 변수 선언들은 렉시컬 환경이라고 불리는 자바스크립트 데이터 구조 내의 메모리에 추가된다.

 

자바스크립트의 모든 선언에서는 호이스팅이 일어난다.

하지만 let, const, class를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작한다.

var와 달리 let 키워드로 선언된 변수를 선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생하는데, 이는 스코프 시작에서 변수의 선언까지 일시적 사각지대(Temporal Dead Zone;TDZ)에 빠지기 때문이다.

 

 

var의 호이스팅

console.log(a); // undefined
var a = "A"; // var 변수

var a를 상단으로 호이스팅하여 변수 선언 전에 console.log로 출력을 해도 에러가 발생하지 않고 undefined가 출력된다.

 

 

let, const의 호이스팅

console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 3;
console.log(a); // ReferenceError: Cannot access 'a' before initialization
const a = 3;

위와 같이 let과 const로 선언된 변수들은 선언하기 전에 사용할 수 없다.

위와 같은 에러가 발생한다고 해서 호이스팅이 되지 않는 것은 아니다.

TDZ에 영향을 받기 때문인데, TDZ에 있는 변수들은 사용할 수 없다.


함수 선언식

함수 전체를 호이스팅한다.

hoisted(); // Output: "This function has been hoisted."

function hoisted() {
  console.log('This function has been hoisted.');
};

 

 

함수 표현식

expression(); //Output: "TypeError: expression is not a function

var expression = function() {
  console.log('Will this work?');
};

 

수 표현식은 호이스팅의 영향을 받지 않아 함수 선언 후 그 아래 코드에서만 호출이 가능하며,

함수 선언식은 함수의 선언 위치에 상관없이 함수 호출이 가능하다.

 

 

class 선언식

class 또한 호이스팅이 발생하는데, 

let, const와 같이 선언 코드 라인을 만나기 전까지는 uninitialized 이다.

즉, TDZ의 영향을 받는다.

let marie = new Person("Marie", 27); // ReferenceError: Cannot access 'Person' before initialization
console.log(marie);
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

변수 생성 3단계

 

자바스크립트에서 변수는 3단계의 생성과정을 거쳐 생성된다.

1. 선언 단계

2. 초기화 단계

3. 할당 단계

 

선언(Declaration): 스코프와 변수 객체가 생성되고, 스코프가 변수 객체를 참조한다. 초기화 전까지는 TDZ 상태이다.

초기화(Initialization): 변수 객체 값을 위한 공간을 메모리에 할당한다. 이 때 할당되는 값은 undefined이다.

할당(Assignment): 변수 객체에 값을 할당한다.

 

var 키워드로 선언된 변수는 선언과 초기화가 동시에 진행되는데, 할당하기 전에 호출하면 error가 발생하지 않고 undefined를 반환한다.

let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 나누어서 진행된다. 스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어지므로 초기화 이전에 변수에 접근하면 참조 에러(Reference Error)가 발생한다.

const 키워드는 재할당 및 재선언이 금지되므로 선언 및 할당을 동시에 해야한다.

 


TDZ에 영향을 받는 구문

1) const 변수

2) let 변수

3) class 구문

4) constructor() 내부의 super()

5) 기본 함수 매개변수 (default function parameter)

TDZ에 영향을 받지 않는 구문

1) var 변수

2) 함수 선언식

 

 

 

참조🙇‍♀️

https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/

https://velog.io/@1nthek/JavaScript-%EB%B3%80%EC%88%98%EC%99%80-%ED%95%A8%EC%88%98-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85Hoisting%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90

https://velog.io/@rkio/Javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85hoisting%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC

https://taenami.tistory.com/87

 

728x90