profile image

L o a d i n g . . .

면접을 보면서 자스기초지식, 네트워크 지식이 모자랐다는 생각이 들어서.
면접 질문들을 조금씩 포스팅 해 볼 생각이다.

변수를 사용하려면 반드시 선언이 필요하다.
변수를 선언할 때는 var, let, const키워드를 사용한다.
ES6 이전까지는 var 키워드만이 JS에서 변수를 선언할 수 있는 유일한 키워드였다. 그러나 var키워드는 여러 단점이 있다.
가장 대표적인 것은 블록레벨스코프를 지원하지않고 함수 레벨 스코프를 지원한다는 점이다. (함수 외부에서 var키워드로 선언한 변수를 코드블록 내에서 선언하면 모두 전역 변수가 된다) 이로 인해 의도치 않게 전역 변수가 중복 선언되어버리는 경우가 생긴다. 또 다른 단점으로는 변수 호이스팅 시 할당 문 이전에 참조해도 값을 반환하여 흐름과 가독성에 오류를 발생시킬 여지를 남긴다.( ES6부터는 블록레벨 스코프 지원을 위해 let키워드를 제공하게 되었다.)

그래서 호이스팅이 뭔데?

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError
  var bar = 1;
  let foo = 2;
}

호이스팅(hoisting) : 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징. 모든 선언문이 런타임 이전단계에서 먼저 실행되기 때문에 var 뿐아닌 let, const, function, function*, class 키워드를 사용해 선언하는 모든 식별자(변수, 함수, 클래스 등)는 호이스팅 된다. 다만 여기서 var와 let, const 차이점은 var는 선언과 초기화가 되어 할당 이전에도 undefined를 출력하지만 let, const는 not initialized 에러가 발생한다.

이 때 let, const 변수 스코프의 맨 위에서 변수의 초기화 완료 시점까지의 변수를
"시간상 사각지대"(Temporal Dead Zone, TDZ)에 들어간 변수라고 표현한다.


console.log(score); //undefined
var score; // 변수 선언

위 예제를 보면 변수 선언문보다 변수를 참조하는 코드가 앞에있다.
JS코드는 인터프리터에 의해 위에서부터 한 줄씩 순차적으로 실행되므로 콘솔출력 이후 다음줄에 있는 코드를 실행한다.
따라서 console.log(score);가 실행되는 시점에는 아직 score변수 선언이 실행되지 않으므로 레퍼런스 에러가 발생할 것처럼보이나. 콘솔에는 undefined가 출력된다.


그 이유는 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점(런타임)이 아닌 그 이전단계에서 먼저 실행되기 때문이다.

이 과정을 더 자세히 이해하기위해 Execution Context; 실행 컨텍스트의 구조또한 살펴보아야 한다.
자바스크립트 엔진은 소스코드 실행 이전 소스코드 평가과정을 거치며 실행준비를 한다. 이 평가과정에서 JS엔진은 변수 선언을 포함한 모든 선언문(변수,함수 선언문 등)을 소스코드에서 찾아내 먼저 실행하고, 평가 과정이 끝난 후 변수 선언을 포함한 모든 선언문을 제외하고 나머지 소스코드를 한 줄씩 순차적으로 실행한다.


실행 컨텍스트는 다른 포스팅으로 따로 정리하겠다



덧붙임
호이스팅은 이제 어떤건지 알겠는데, 왜? 그래서 호이스팅이 왜 있는건데? 는 실행컨텍스트를 공부하면서 알 수 있게되기를 바란다. 왜?를 찾다보니 렉시컬 스코프도 나오고 모듈도 나오는데 아마 답을 찾으려면 조금 더 시간이 걸리지 않을까 싶다. 선언 - 초기화 - 할당도 실행 컨텍스트를 조금 더 공부해봐야 var와 const,let의 작동원리를 이해할 수 있을것같다.


참고:
- 모던자바스크립트 Deep Dive (이웅모), 위키북스
- https://developer.mozilla.org/ko/docs/Glossary/Hoisting
-https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let#%EC%8B%9C%EA%B0%84%EC%83%81_%EC%82%AC%EA%B0%81%EC%A7%80%EB%8C%80

- https://devowen.com/363

반응형
복사했습니다!