면접시 대답
자바스크립트에서 호이스팅이란, var 선언문이나 함수 선언문 등 모든 선언문이 해당 스코프의 선두로 옮겨진 것처럼 동작하는 특성을 말합니다.
여기서 var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화 합니다.
즉, 변수의 선언와 초기화가 동시에 이루어 집니다. 먼저 호이스팅 var,let,const 에서 var는 선언과 초기화가 동시에 이루어지고 let과 const는 선언과 초기화가 나누어져 이루어집니다
이때 선언과 초기화 사이를 TDZ(Temporal Dead Zone)이라고 합니다 TDZ에 있는 코드에 접근하게 되면 Reference Error가 발생하게 됩니다
호이스팅에 대한 나의 이야기
a = 2;
var a;
console.log(a); // (1)
(1) 식의 실행결과는 무엇일까? 정상적으로(?) 2가 출력된다.
그렇다면
console.log(a); // (2)
var a = 2;
(2) 식의 실행결과는 무엇일까? 답은 2가 아니라 undefined이다.
위 두 결과를 모두 맞추었다면 당신은 호이스팅을 어느정도 이해한다고 생각한다
허나, (2)식을 2로 대답한 나는 왜 (2) 식의 답이 undefined가 나오는지 지금부터 기록할 것이다.
누군가는 var a = 2 를 하나의 구문으로 볼 수 있겠지만
실제로 자바스크립트는
var a, a = 2 이렇게 두 개의 독립된 구문으로 본다.
(
그럼 여기서 어려운 질문!
- 그럼 왜 저렇게 두 개의 구문으로 나누어 지는 것일까?
대답은 자바스크립트 엔진은 인터프리팅 하기 전에 그 코드를 먼저 컴파일하기 때문 이라고 할 수 있겠다.
허나 인터프리팅이 뭔지 컴파일이 뭔지는 정확히 머리로 이해되지 않고 지금 주제와 벗어나
나중에 공부하기로 하자.
https://hashcode.co.kr/questions/7560/javascript-자바스크립트는-컴파일언어인가요-인터프리터-언어인가요
)
그래서 실제로 (2) 식은
var a;
console.log(a);
a = 2;
가 되고 할당이 되기전에 console.log을 찍으므로 undefined가 되는것이다.
여기서 var a 부분이 갑자기 맨 위로 올라가 코드 실행이 되는데
이 과정을 정리하면 변수와 함수 선언문이 선언된 위치에서 해당 스코프의 선두로 ‘옮긴것처럼' 동작하는것을 호이스팅이라고 한다.
function sum(a,b) {} , a = function (a, b) {}
참고로 함수 표현식은 끌어올려지지 않는다.(왜???)
자 그런데 돌아와서 (2) 식을 조금 비틀어 보자.
console.log(a); // (3) ReferenceError: Cannot access 'a' before initialization
let a = 2;
=>
let a;
console.log(a)
a = 2
(2)식의 내용 중 var 에서 let 으로 바꿨을 뿐인데 왜 레퍼런스 에러가 뜰까?
바로 TDZ 때문이다.
TDZ에 대한 나의 이야기
우선 변수의 생성과정 3단계에 대해 잠깐 이야기 해보자.
- 선언단계 : 변수를 실행 컨텍스트의 변수 객체에 등록한다. 이 변수 객체를 스코프가 참조한다.
- 초기화단계: 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다. 이때 변수는 undefined가 된다.
- 할당단계: undefined로 초기화된 변수에 실제 값을 할당한다.
var 는 호이스팅이 발생하면, 선언과 초기화가 동시에 이루어진다.
실행 시점의 스코프 최상단에서 해당 변수에 대한 메모리가 살아있기 때문에 선언부 위치에 상관 없이 참조ㅡ 할당이 가능하다.
그.러.나
let, const 는 호이스팅이 발생하면, 선언만 이루어지고 실행시점에서 실질적인 선언부를 만날 때까지 초기화는 이루어지지 않는다. 이 간극만큼 해당 변수에 대한 메모리는 존재하지 않기 때문에 선언부 상단에서 참조, 할당이 불가능하다.
이때 스코프의 진입지점과 해당 식별자의 실질적 선언부 사이를 일시적 사각지대, TDZ 라고 한다.
{
// TDZ가 스코프 맨 위에서부터 시작
const func = () => console.log(letVar); // OK
// TDZ 안에서 letVar에 접근하면 ReferenceError
let letVar = 3; // letVar의 TDZ 종료
func(); // TDZ 밖에서 호출함
}
위 코드가 정상적으로 동작하는 이유는 함수의 호출지점이 사각지대 밖이기 때문이다.
'스터디 > JS,Node.js' 카테고리의 다른 글
브라우저 저장소 (쿠키, 로컬 스토리지, 세션 스토리지) (0) | 2023.08.17 |
---|---|
callback, promise, async/await 의 특징과 차이점에 대해서 설명하세요. (0) | 2022.06.19 |
클로져에 대해서 설명하세요. (0) | 2022.06.19 |