호이스팅

fe_sw·2022년 7월 31일
0

Javascript

목록 보기
9/22

변수,함수 선언문이 스코프 내의 최상단으로 끌어올려지는것 같은 현상 을 말한다.


1.자바스크립트 엔진은 코드를 실행하기 전 실행 가능한 코드를 형상화하고, 구분하는 과정(*실행 컨텍스트를 위한 과정)을 거친다

2.자바스크립트 엔진은 코드를 실행하기 전 실행 컨텍스트를 위한 과정에서 모든 선언(var, let, const, function, class)을 스코프에 등록한다.


코드 실행 전 이미 변수선언/함수선언이 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작한다.(정확히는 var 키워드로 선언한 변수와 함수 선언문일 경우 오류 없이 동작한다. 이는 선언이 스코프 맨 위로 끌어올려진 것 처럼 보이게 한다.)

실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경을 의미하고, 실행되기전 이러한 실행 컨텍스트 과정(코드를 구분하는 과정)을 거친다.

변수 호이스팅

var 키워드는 변수 호이스팅에 의해 런타임 이전에 변수가 선언되어 undefined를 출력한다 하지만 let 키워드에서는 참조에러가 나타난다.

var 키워드는 '선언 단계'와 '초기화 단계가 동시에 일어나는데 undefined로 초기화된다.

let 키워드로 선언한 변수는 '선언 단계'와 '초기화 단계'가 분리되어 진행된다. (선언,초기화,할당)
즉, 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 메모리에 저장되지만, 초기화 단계는 변수 선언문에 도달했을 때 실행된다.

만약 초기화 단계가 실행되기 이전에 변수에 접근하려고 하면 참조 에러가 발생한다.
let 키워드로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점(변수 선언문)까지 변수를 참조할 수 없다.

스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 일시적 사각지대(TDZ: Temporal Dead Zone) 라 부른다.

즉 var만 호이스팅이 일어난다고 착각할 수 있는데, 사실 var let const전부 호이스팅이 일어난다.
단지 선언단계와 초기화단계가 분리되냐 아니냐의 차이일뿐 이다.


console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

// 런타임 이전에 선언 단계가 실행된다. 아직 변수가 초기화되지 않았다.
// 초기화 이전의 일시적 사각 지대에서는 변수를 참조할 수 없다.

함수 호이스팅

함수 호이스팅은 선언문에만 해당하는데, 함수 표현식은 결국 어떠한 변수로 함수를 할당하는 모양새여서 이것 또한 변수 호이스팅 사례로 볼 수 있기 때문이다.


foo1(); // 함수 선언문에서는 함수 호이스팅 일어난다.
foo2(); // 함수 표현식이라서 함수 호이스팅 일어나지 않는다(변수 호이스팅).
function foo1() {
  console.log('Hello');
}
var foo2 = function() {
  console.log('world');
}

함수선언문은 변수선언과 마찬가지로 자바스크립트 엔진에 의해 코드 실행 전 이미 메모리에 변수선언/함수선언이 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작한다


func(); //Uncaught TypeError: func is not a function
var func = function() {}

여기서는 변수 func의 호이스팅이 발생해서 참조할 수는 있기 때문에 ReferenceError가 발생하지 않지만 그 값이 undefined 이기 때문에 TypeError가 발생한다.


func();
var func = function(){ console.log('변수 호이스팅') }
function func() {
  console.log('함수 호이스팅');
}

함수와 변수 선언문 중에는 함수 선언문이 먼저다.

변수 라이프사이클

선언 단계 (Declaration phase)

변수를 실행 컨텍스트의 environmentRecord에 등록
environmentRecord는 스코프가 참조하는 대상

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

초기화 단계 (Initialization phase)

environmentRecord에 등록 된 변수를 위한 메모리를 확보
이 단계에서 변수는 undefined로 초기화

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

할당 단계 (Assignment phase)

undefined로 초기화 된 변수에 실제 값을 할당

0개의 댓글