본문 바로가기

study/JavaScript

Js - 호이스팅 간단히 이해하기

호이스팅이란

  • 코드를 실행하기 전에 변수와 함수의 선언을 해당 스코프의 최상단으로 끌어올리는 것이 아니다.
  • 코드를 실행하기 전에 변수와 함수의 선언을 해상 스코프의 최상단으로 올린 것처럼 보이는 현상이다.
  • 자바스크립트 엔진은 코드를 실행하기 전 실행 컨텍스트를 위한 과정에서 모든 선언(var, let, const, function, class)을 스코프에 등록한다.
  • 코드 실행 전 이미 메모리에 선언된 변수나 함수가 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작한다. => var키워드와 함수 선언문만 오류 없이 동작하며(undefined), let, const 변수는 참조 오류가 발생한다.
  • 선언이 코드 실행보다 먼저 메모리에 저장되는 과정으로 인한 현상이다.

 

변수의 호이스팅

  • 모든 변수 선언에는 호이스팅이 일어난다.
  • 그런데 let, const를 이용한 변수 선언은 호이스팅이 발생하지 않는 것처럼 동작한다.
  • var 키워드로 선언된 변수와는 달리 let 키워드로 선언된 변수를 선언문 이전에 참조하면 참조 에러가 발생한다.

 

변수의 생성

변수는 3단계에 걸쳐 생성이 된다.

 

1단계: 선언 

  • 변수를 실행 컨텍스트의 변수 객체에 등록한다.
  • 이 변수 객체는 스코프가 참조하는 대상이 된다.

2단계: 초기화 

  • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다.
  • 초기화 단계에서 변수는 undefined로 초기화된다.

3단계: 할당

  • undefined로 초기화된 변수에 실제 값을 할당한다.

var로 선언한 변수는 선언 단계와 초기화 단계가 한 번에 이뤄진다. 즉, 스코프에 변수를 등록(선언 단계)하고 메모리에 변수를 위한 공간을 확보한 후, undefined로 초기화한다. 따라서 변수 선언문 이전에 변수에 접근하여도 스코프에 변수가 존재하기 때문에 에러가 발생하지 않으며, undefined를 반환한다. 이후 할당 단계에 들어가면 값이 할당된다.

let, const 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 즉, 스코프에 변수를 등록(선언 단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이뤄진다. 초기화 이전에 변수에 접근하려고 하면 참조 에러가 발생한다. 이는 아직 변수가 초기화되지 않았기 때문이다. 즉, 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다. 따라서 스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다.

 

변수의 호이스팅 예시

var

// 변수 선언이 변수의 호출시점보다 아래 있지만 호이스팅으로 인해 오류가 발생하지 않는다.
// name는 var로 선언된 변수이기 때문에 선언+초기화 단계가 진행되었다.
console.log(name); // undefined
// 할당까지 이루어짐
name = 'sikk';
var name;
console.log(name); // sikk

let

// 호이스팅이 발생 하였지만 초기화가 되지않은 상태에서 참조해서 참조오류 발생
console.log(name); // 참조오류 발생
let name; // 3번 라인에서 초기화 단계가 시작됨
console.log(name); // undefined

const

const text; // 에러 발생 const는 재할당이 불가능하기 때문에 선언과 할당이 동시에 일어나야 한다.

 

함수의 호이스팅 예시

함수 선언문에서는 호이스팅이 발생하여 정상 동작을 하지만, 함수 표현식에서는 호이스팅이 발생하지 않아 오류가 발생한다.

sik1(); // 함수 선언문에서는 호이스팅 일어난다. 결과 = hello sik
sik2(); // 함수 표현식이라서 호이스팅 일어나지 않는다. 결과 = error
function sik1() {
  console.log('hello sik1');
}
var sik2 = function() {
  console.log('hello sik2');
}

 

 결론

  • 코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 한다.
  • 호이스팅을 제대로 모르더라도 함수와 변수를 가급적 코드 상단부에서 선언하면, 호이스팅으로 인한 스코프 꼬임 현상은 방지할 수 있다.
  • let/const를 사용한다.

'study > JavaScript' 카테고리의 다른 글

Js - 어휘적 환경(Lexical Environment)과 클로저(Closure)  (0) 2022.11.18
Js - 스코프(Scope)  (0) 2022.11.17
Js - JSDoc  (0) 2022.08.24
Js - 사용자의 os 가져오는 방법  (0) 2022.04.14
Js - var, let, const의 차이점  (0) 2022.02.17