본문 바로가기
개발 기초 다지기

호이스팅과 클로져

by 너의고래 2024. 6. 27.
반응형

그간 공부했던 것들을 복습할 수 있는 마지막 기회인 오늘 무엇을 복습하는 것이 가장 적절할까 고민하던 중 기초때 배웠던 호이스팅과 클로져가 떠올랐다. 그 이후로 배운 실제로 코딩할 때 사용하는 것들은 하다보면 익숙해짐으로써 알게되는 과정이라면 이 부분의 경우 지금이 아니면 나중에 복습하기 정말 쉽지 않을 것 같았다. 그렇게 오랜만에 호이스팅과 클러져 개념에 대해 찾아보았다.

 

개발에 대해 정말 하나도 모르던 시절(그래봤자 1~2달 전이지만) 나름 열정이 가득했어서 진짜 자료를 보고 보고 또 봐서 이해하려했는데, 도무지 이해가 가지 않았었다. 이 개념을 이해하기 위해 블록 스코프, 함수 스코프 등등을 알았어야 했는데 그것들에 대한 개념도 제대로 잡혀있지 않다보니 쉽지 않았던 것 같다. 지금도 다시 봐도 그렇데 와닿지는 않아서 이것저것 찾아보다 한 번에 이해가 가게 도와주는 자료를 찾았다.

 

호이스팅 자료

https://hanamon.kr/javascript-호이스팅이란-hoisting/

 

 

[JavaScript] 호이스팅(Hoisting)이란? - 하나몬

❗️호이스팅이란? 호이스팅은 코드를 실행하기 전 변수선언/함수선언을 해당 스코프의 최상단으로 끌어올리는 것이 아니다. 호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프

hanamon.kr

 

클로져 자료

https://youtu.be/tpl2oXQkGZs?si=VwhOdJVPOPhU6Te1

 

 

이 자료들을 기반으로 내가 이해한 각 개념을 정리해보겠다.

 

호이스팅

호이스팅은 도달하지 않은 선언이 끌어올려져서 사용되는 것을 의미한다.

우선 자바스크립트 엔진 코드를 실행하기  실행 가능한 코드를 형상화하고 구분하는 과정(*실행 컨텍스트를 위한 과정) 거치기 때문에

함수, 변수 모두 호이스팅이 일어난다.

 

하지만 호이스팅이 일어나도 함수와 var 변수의 경우 정상적으로 작동하는데,

let과 const 변수의 경우에는 오류가 발생하는데, 이를 이해하려면 변수의 생성 절차를 먼저 이해해야 한다.

 

Step1. 실행 컨텍스트 등록 단계 - 실행 컨텍스트에 이름이 올라가는 단계(메모리에는 저장되지 않음)

Step2. 초기화 단계 - 메모리에 undefined 상태로 저장

Step3. 할당 단계 - 값이 메모리에 할당 됨

 

같은 변수이지만 var 같은 경우 선언과 동시에 초기화가 이루어지기 때문에 선언 전 호출해도 'undefined'를 반환하는 반면, let과 const는 해당 선언문에 도달 후에 초기화가 이루어진다. 그렇기 때문에 let과 const는 선언 전 참조하려고 하면 '참조오류'가 발생한다.

 

//함수 선언

foo(); // 정상 출력
function foo() {
  console.log('Hello, world!');
}


//변수(var) 선언
console.log(a); // undefined 출력
var a = 10;


//변수(let, const) 선언
console.log(b); // ReferenceError 발생
let b = 20;

클로저

클로저는 함수가 선언될 때 그 함수가 속한 스코프(환경)를 기억하고, 함수가 호출된 이후에도 그 스코프에 접근할 수 있는 기능을 말한다.

즉, 클로저는 함수와 그 함수가 선언될 당시 렉시컬 환경의 조합이다.

  1. 함수가 자신이 선언될 당시의 스코프를 기억하고, 나중에 그 스코프에 접근할 수 있다.
  2. 외부 함수의 변수를 내부 함수에서 참조할 수 있으며, 그 변수는 외부 함수가 실행을 마친 후에도 사라지지 않고 유지된다.
function outer() {
  let count = 0;  // 외부 함수의 변수
  return function inner() {
    count++;  // 외부 함수의 변수를 참조
    console.log(count);
  };
}

const closureFunc = outer();
closureFunc();  // 1
closureFunc();  // 2
closureFunc();  // 3

전역 lexical 환경

  • outer = inner
  • count = 0

outer lexical 환경

  • 없음

위 예시에서는 inner 함수는 outer 함수가 종료된 후에도 count 변수에 접근할 수 있으며, 그 값을 계속해서 변경할 수 있다. 이런 특성이 바로 클로저의 본질.

 

 

처음 이 개념을 접했을때는 감도 잡히지 않았지만, 해당 개념들을 다루는 자료들을 이것저것 살펴보니 조금씩 감이 오기 시작한다. 눈에 실제로 보이지 않는 것을 이해한다는 것이 가끔 많이 어렵게도 느껴지지만 이게 또 개발의 묘미가 아닐까 생각이 든다.

반응형

댓글