클로저, 호이스팅이 '현상'이라고 불리는 이유

이수보🧑🏻‍💻·2024년 5월 27일
1

기타

목록 보기
13/13

이 주제를 선택한 이유

자바스크립트를 공부하다 보면 클로저나 호이스팅을 설명할 때 자주 등장하는 표현이 있습니다.
바로 "이것은 자바스크립트의 현상이다"라는 말입니다.

이 표현을 처음 접하면, 마치 "그냥 그렇게 되는 거야"라는 식의 모호한 설명처럼 들릴 수 있고 흘려 넘기기 쉽습니다.
하지만 조금만 더 깊게 들어가 보면, 왜 이것이 '현상'이라는 단어로 설명되는지를 이해할 수 있습니다.

그래서 이번 기회에 제가 클로저와 호이스팅에 대해 공부하면서 느낀 '현상'이라고 불리는 이유에 대해 적어보려고 합니다.

📌 '현상'이라는 단어의 의미

현상이라는 단어는 일상 언어에서 단순히 무언가가 일어난 결과를 의미하지 않습니다.
나무위키에서는

"주목할 가치가 있고 조사할 만한 모든 사건" 이라고 정의합니다.
단순한 결과가 아닌, 이유를 탐색하고 분석할 가치가 있는 대상이라는 뜻으로 해석됩니다.

즉, 그것이 단순히 작동한다는 것을 넘어 "왜 그렇게 작동하는가?"라는 질문을 가지고 있습니다.

따라서, 클로저와 호이스팅 현상을 주목할 가치가 있고 조사하고 분석해야 한다고 생각했습니다.

🎯 클로저가 '현상'인 이유

function makeCounter() {
  let count = 0;
  
  return function () {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2

위 코드를 보면 makeCounter() 함수는 이미 종료되었습니다, 하지만 makeCounter함수 내부의 count변수는 여전히 유지되고 접근할 수 있는 것을 확인 가능합니다.
이 특이한 동작이 바로 클로저 현상이라 불리는 이유입니다.

이를 이해하려면 렉시컬 스코프실행 컨텍스트 구조를 알아야한다고 생각합니다.

렉시컬 스코프란?

렉시컬은 정적이라는 뜻으로 초월번역을 하고 원래의 뜻은 어휘 라는 뜻입니다.
헷갈리는 개념이지만 JS의 스코프는 함수가 실행될 때 생기는 것이 아니라, 함수 선언 시 소스코드평가 단계에서 생성이 됩니다.
따라서, 선언된 위치 기준으로 상위 스코프를 스코프체인으로서 가집니다. 즉, 이를 정적인 스코프라 하여 렉시컬 스코프라고 하는 것입니다.

실행 컨텍스트란?

실행 컨텍스트는 전역 컨텍스트함수 컨텍스트로 나눌 수 있습니다.
최초 실행시 모든 변수, 함수들을 가진 전역 컨텍스트가 생성이 되고, 함수 실행 시 마다 함수 실행 컨텍스트가 생성이 됩니다.
모든 컨텍스트는 최초 생성 시 렉시컬 스코프를 참조하여 스코프 체인 및 this, arguments를 가지고 생성됩니다.

즉, 클로저는 실행 컨텍스트가 생성되며 렉시컬 스코프의 스코프 체인을 참조하며 외부 함수의 변수에 접근할 수 있는 구조적으로 렉시컬 스코프와 실행 컨텍스트 개념에서 파생되는 현상입니다.

따라서 클로저는 단순히 값을 기억하는 현상이 아니라

"함수 실행 시점에 사라졌을 것 같은 외부 변수 스코프를, 실행 컨텍스크가 생성되며 외부 렉시컬 스코프를 참고하기 때문에 메모리에 남아 유지되는 구조적 🎯현상"입니다.

🎯 호이스팅이 '현상'인 이유

호이스팅은 변수나 함수 선언이 소스 코드 상의 위치와 상관없이 코드 실행 전 최상단으로 끌어올려지는 동작을 의미합니다.

console.log(varVal); // undefined
declarFunc(); // "Declaration Function"

console.log(letVal); // ReferenceError: Cannot access 'letVal' before initialization"
console.log(constVal); // ReferenceError: Cannot access 'constVal' before initialization"
expressFunc();// ReferenceError: Cannot access 'expressFunc' before initialization"

var varVal = "var";
let letVal = "let";
const constVal = "const";

function declarFunc() {
  console.log("Declaration Function");
}

const expressFunc = function() {
  console.log("Express Function");
}

위 코드를 보면 var, let, const, 함수 선언문/표현식 어떤 것으로 변수, 함수를 선언하든 일단은 최상단으로 끌어올려져 즉, 호이스팅 되어 undefinedCannot access Error를 발생시키는 것을 확인 가능합니다.

이 특이한 동작이 바로 호이스팅 현상이라 불리는 이유입니다.
이러한 동작을 이해하려면 소스 코드 평가 단계를 알아야한다고 생각합니다.

소스 코드 평가 단계란?

JS의 코드가 실행되는데 크게 3가지의 순서가 필요합니다.

  1. 소스 코드 평가
  2. 실행 컨텍스트 생성
  3. 코드 실행

소스 코드 평가 단계는 실행 컨텍스트가 실행 되기 전에 실행되는 단계로 변수, 함수 선언을 먼저 메모리에 등록합니다.
이때,

  • var는 선언과 동시에 초기화까지 이뤄진 채 메모리에 등록됩니다.
  • let, const는 선언만 이뤄진 채 메모리에 등록되고 TDZ 상태에 놓입니다.
  • function은 함수 내부가 평가되지 않은 채 함수 전체가 메모리에 등록됩니다.

이후에는 실행 컨텍스트가 생성되며 메모리에 등록된 변수, 함수로 렉시컬 환경을 생성합니다.

이러한 소스 코드 평가 단계에서의 메모리 등록은 개발자 입장에서는 "선언보다 먼저 사용했는데도 마치 끌어올려 진 것만 같은 결과가 나오기 때문에" 현상으로 인식됩니다.

소스 코드 평가 단계에서 실행 순서에 의해 변수와 함수가 메모리에 등록되며 생기는 구조적 현상입니다.

따라서 호이스팅은 단순히 끌어 올려지는 현상이 아니라

"소스 코드 평가 단계에서 다음 실행 컨텍스트 생성을 위해 변수와 함수를 메모리에 등록해 놓는 동작으로 인해 생기는 구조적 🎯현상입니다.

✅ 결론

현상은 주목할 가치가 있고 이유를 탐색하고 분석할 가치있는 대상을 의미하는 것처럼 클로저호이스팅이 현상이라고 불리는 이유에 대해 파악하다 보니,
렉시컬 스코프, 실행 컨텍스트, 소스 코드 평가와 같이 다양한 개념도 함께 공부하는 좋은 기회가 되었습니다.

이러한 과정을 통해 단지 "어떻게 동작하는가"를 넘어서 "왜 그렇게 동작하는가"를 이해하는 자세의 중요성을 깨달았습니다.

앞으로도 눈 앞에 보이는 코드의 흐름만이 아니라 그 코드 뒤에 숨겨진 원리와 구조를 꾸준히 파악해 나가다 보면 좋은 개발자가 될 수 있다고 생각하는 계기가 되었습니다.

0개의 댓글

관련 채용 정보