개발/JavaScript

[JavaScript] 함수 선언문과 함수 표현식의 차이 (feat: 호이스팅이 뭔데?)

알파카털파카 2023. 2. 25. 19:31

 

 

코어 자바스크립트 책의 실행 컨텍스트 파트를 읽다가 함수 선언문과 함수 표현식의 차이를 깨우치게 되었다. 이 책은 내가 개발을 처음 시작하고 얼마 안 되었을 때 처음 읽었고, 작년 말쯤 또 읽고, 이번에 3번째 읽는 것이다. 처음 읽을 때는 한 페이지 읽는 데 한참을 붙들고 있었는데, 그래도 여러번 보니 예전보단 수월하게 읽혀서 그동안 스스로가 성장한 것 같아 뿌듯했다😊 인프런에서 해당 책의 내용을 다룬 정재남님의 강의도 2번 보았다(2회차 진행 중이다). 

 

실행 컨텍스트가 면접 단골 질문인 것도, 자바스크립트의 핵심 개념 중 하나인 것도 알고는 있지만, 내게는 각종 어쩌구 environment 라는 단어가 잔뜩 나오는 어려운 내용으로 각인되어 있었다. 대강의 흐름은 알았지만 말로 설명하기 어려워서 이번엔 반드시 체화시키려고 노력했다. 그러면 이제 내가 깨달은 내용을 적어보겠다.

 

 


 

 

1. 실행 컨텍스트란?

실행 컨텍스트란, 코드가 실행되는 데에 필요한 환경 정보가 담긴 객체이다.

 

 

2. 실행 컨텍스트의 구성

실행 컨텍스트가 어떻게 구성되어 있는지 알아보고, 함수 선언문과 함수 표현식의 커다란 차이점인 호이스팅이 어디서 발생하는지 따라가보도록 할 것이다. 구조를 자세하게 쓰려고 한 이유는 내가 실행 컨텍스트를 어려워했던 이유 중에 '구조가 복잡해 보인다'는 점이 있었기 때문이다.

 

실행 컨텍스트

실행 컨텍스트는 3가지로 구성되어 있다. 

1. VariableEnvironment

2. LexicalEnvironment ✅

3. ThisBinding

 

함수 선언문과 함수 표현식에 관한 내용은 LexicalEnvironment와 관련이 있다. LexicalEnvironment를 자세히 살펴보자.

 

LexicalEnvironment

LexicalEnvironment도 2가지로 구성되어 있다. 2번의 내부 구성요소이므로 '2-n'번호를 붙였다.

2-1. environmentRecord ✅

2-2. outerEnvironmentReference

 

호이스팅은 이 중 environmentRecord에서 일어난다. outerEnvironmentReference은 스코프 체인과 연관이 있지만 이 글에서는 호이스팅만 알아볼 것이다.

 

호이스팅

실행 컨텍스트 ➡️ LexicalEnvironment ➡️ environmentRecord

 

environmentRecord에서는 식별자의 정보가 수집된다. 실행 컨텍스트가 생성될 때 맨 처음 수행되는 작업이다. 식별자 정보는 순서대로 수집된다. 변수는 선언부만, 함수 선언은 함수 전체가 수집된다. 이 작업을 호이스팅(끌어올리는 작업)이라는 가상 개념으로 표현한다.

 

// 함수 선언문
function exampleA () {}

// 함수 표현식
const exampleB = function () {}

 

💡 함수 선언문은 그 전체가 수집되는 반면, 함수 표현식은 함수를 담아놓은 변수만 수집된다. 표현식은 변수에 함수를 할당한 것이기에, 함수 전체가 수집되지 않는다.

 

// 호이스팅이 되었을 때
function exampleA () {} // 함수 선언문 전체가 수집
const exampleB // 함수 표현식의 변수 선언 부분만 수집

// 함수 표현식
exampleB = function () {}

 

맨 처음 자바스크립트를 배울 때 '함수는 이런 방법들로 선언할 수 있습니다.'에서 배운, 두 함수 정의 방법 간에 호이스팅 여부 차이가 생기는 원리를 지금 와서 깨우치게 되었다! 솔직히 말하자면, 이 둘의 차이가 발생하는 이유를 깊이 생각해본적 없이 그냥 사용해 왔었다🥲 '함수 선언문은 아무데서나 함수를 호출해 사용할 수 있기 때문에 초보자에게 편리하다, 그렇지만 동일한 함수명으로 중복해서 선언할 경우 어디서 오류가 발생했는지 추적하고 디버깅하기 어렵다'는 내용은 알고 있었지만 실행 컨텍스트를 배우는 중에 만나게 되니 신기하고 재밌었다. 

 

 


 

 

여러번 읽고 코드를 따라치며 실습해보니 그 어렵던 실행 컨텍스트도 많이 이해가 되었다. 어려운 용어도 많이 접해서 익숙해졌다. 개발자의 좋은 점 중 하나는, 일반인은 못 알아듣는 언어로 소통한다는 점인데(적고 보니 단점 같기도😂) 그런 부분에서 나의 지적 허영심..이 채워져서 보람을 느낀다. 이것저것 많이 알게 되었을 때 뿌듯해하는 나이기에.. 이 또한 하나의 동기부여다😇