면접으로 바쁜나날이라 다양한 정리들을 노션으로 간단하게 진행하고 있는 요즘이다.
그럼에도 불구하고 이 글을 쓰는 이유는 면접에서 꼭 찾아보면 좋다고 하셔서 필수 기본지식 중 하나라여겼기 때문이다🧐.
일단 MDN을 찾아봤다.
MDN에서는
호출스택(call stack)은 여러 함수들을 호출하는 스크립트에서 해당 위치를 추적하는 interpreter를 위한 메커니즘이라고 설명되어있다.
문제는 난 인터프리터가 뭔지 모르므로 ? 또 찾아봤다.
인터프리터 언어란 프로그래밍언어의 소스코드를 바로 실행하는 컴퓨터 프로그램 또는 환경을 말한다고 한다.
적어도 아래의 세가지 조건을 만족해야한단다.
쉽게 말해서 컴파일러는 고급언어(프로그래멍언어 같은 것들 그러니까 서버로 부터 가까운 것 보다 유저로 부터 가까운 언어라고 말하면 되려나.. 이런 언어)
로 작성된 원시코드 명령어들을 한번에 한줄씩 읽어 들여서 실행하는 프로그램이다.
출처: 네이버 지식백과
그래서 호출스택은 아래와 같은 작동 순서를 가진다고 한다.
function greeting(){ //codecode1 sayHi(); //codecode2 } function sayHi(){ return "Hi!"; } //greeting 함수 호출 greeting(); //codecode3
예시를 통해 이해를 해보겠다.
일단 기명함수로 greeting() 과 sayHi()가 있다.
greeting()이 호출되어있다.
greeting이 호출되니 greeting 이라는 함수를 호출 스택리스트에 추가하게 된다.
이때 호출스택리스트에는 greeting이 존재한다.
이제 greeting이 추가되고 난 다음 함수 내부의 모든 코드를 실행한다.
여기서 sayHi 함수가 호출이 된다.
그럼 호출스택리스트에는 sayHi가 추가된다.
이때 호출스택리스트에는 greeting, sayHi가 존재한다.
sayHi함수의 끝까지 실행을 하게 된다(함수 내부의 모든 코드 실행)
sayHi가 호출된 라인(codecode1과 2의 사이)로 돌아온다.
그리고 남아있는 greeting()함수를 계속 실행한다.
호출스택리스트에서 sayHi()함수를 제거한다.
이때 호출스택리스트에는 greeting이 존재한다.
- Q: 왜 돌아온다음 스택리스트에서 제거가 될까(제거하고 돌아가면 안되나?)
이제 greeting함수 내부의 모든 코드가 실행되었을때, 이를 호출한 라인으로 돌아와 js 코드의 나머지를 계속 실행한다.
호출스택리스트에서 greeting()함수를 제거한다.
이때 호출스택리스트는 비었다.
따라서 빈 호출스택으로 시작하여 함수를 호출할 때 마다 자동으로 호출스택에 추가되고, 해당코드가 모두 실행된 후, 호출스택에서 자동으로 제거가된다.
그래서 끝은 빈 호출스택으로 끝난다.
이유를 알기 위해서는 실행컨텍스트와 재귀함수에 대한 이해가 필요한 것 같다.
실행컨텍스트는 아주 간략하게 말해서 코드가 실행되어야 할때 이의 환경정보를 저장한 객체라고 생각하면된다.
재귀함수는 함수자신이 자신을 다시 부르는것이다.(매우간략)
재귀함수에 관해서는 다른 블로그에서 정리해보겠다.
function pow(x, n) {
if (n == 1) {
return x;
} else {
return x * pow(x, n - 1);
}
}
alert( pow(2, 3) ); // 8
처음 하는 호출을 포함한 중첩 호출의 최대 개수는 재귀 깊이(recursion depth) 라고 합니다. pow(x, n)의 재귀 깊이는 n이다.
자바스크립트 엔진은 최대 재귀 깊이를 제한한다.
이때 콜스택을 생각하면 된다.
코어자바스크립트의 설명에 따르면
만개 정도까진 확실히 허용하고, 엔진에 따라 이보다 더 많은 깊이를 허용하는 경우도 있습니다.
하지만 대다수의 엔진이 십만까지는 다루지 못합니다.
이런 제한을 완화하려고 엔진 내부에서 자동으로 'tail calls optimization’라는 최적화를 수행하긴 하지만, 모든 곳에 적용되는 것은 아니고 간단한 경우에만 적용됩니다.
정리하자면 콜스택이란 함수가 호출되면 쌓이고 실행이 끝나면 스택에서 제거된다.
콜스택은 재귀함수를 사용할 때의 경우 그 깊이가 정해져있고 대략 1만 정도까지 허용한다고 생각하자(그게 안전)
졸리니까 to be continue..