자바스크립트 콜스택의 이해 - Lee-hyuna/33-js-concepts-kr GitHub Wiki
자바스크립트 엔진은 힙과 단일 호출 스택으로 구성된 단일 스레드 인터프리터 이다. 브라우저는 DOM, AJAX 그리고 Timers 과 같은 웹 API를 제공하고 있다.
이글은 콜 스택이 무엇이고, 왜 필요한지에 대한 설명에 초점을 맞출것이다. 콜 스택을 이해하는 것은 자바스크립트 엔진이 함수 계층과 실행 순서를 이해하는데 도움이 될것이다.
콜 스택은 주로 함수의 실행을 위해 사용된다. 하지만 콜 스택은 하나이고, 함수 실행은 위에서부터 아래로 한번에 하나씩 실행이 된다. 이것은 콜 스택이 동기식이라는것을 뜻한다.
콜 스택을 이해하는 것은 비동기 프로그래밍을 하는데 있어서 아주 중요합니다.
비동기 적인 자바스크립트는 콜백 함수, 이벤트 루프, 그리고 task 큐가 있습니다. 콜백 함수는 이벤트 루프에 의해 콜백 함수가 스택에 푸시 된 후 실행 중 콜 스택에 의해 작동됩니다.
먼저 이 질문의 답을 생각해보자 - 콜 스택은 무엇인가?
가장 기본적인 레벨에서, 콜 스택은 임시 저장과 함수의 호출을 관리하기 위한 Last In, First Out(LIFO) 의 원리 데이터 구조이다.
이 정의를 다시한번 파해쳐보자.
LIFO: 우리가 콜 스택을 이야기할때 Last In, First Out의 원리로 작동한다고 알고있다. 이것은 스택에 마지막으로 들어간 함수가 리턴될때 처음으로 스택에서 튀어 나옴을 의미한다.
다음 LIFO를 증명하는 코드 샘플을 보자.
function firstFunction() {
throw new Error("Stack Trace Error");
}
function secondFunction() {
firstFunction();
}
function thirdFunction() {
secondFunction();
}
thirdFunction();
해당 코드가 동작할때, 우리는 error를 만날 수 있다. 여기서 함수들이 어떻게 위에서부터 쌓였는지 스택이 출력이 된다. 다음 다이어 그램을 보자.
우리는 firstFunction()
부터 시작되어져 있는 스택 정렬을 볼수 있다. ( 이것은 가장 마지막에 스택에 들어갔음을 의미하고, 이 함수에서 에러가 방출되었다는 것을 알 수 있다. ) 다음 secondFunct()
, 그리고 그다음thirdFunction()
이다. ( 이 thirdFunction()은 코드가 처음실행 될때 가장 먼저 스택에 들어간것이다. )
임시 저장소: 함수가 실행이 될때(호출할때), 함수와 , 그 함수의 파라미터, 그리고 변수들을 스택 프레임을 형성하기 위해 콜스택 안으로 집어 넣는다. 이 스택 프레임은 스택안의 메모리 장소이다. 이 메모리는 함수가 스택에서 리턴 되었을때 비워지게 된다.
함수 실행 관리: 콜 스택은 각 스택 프레임의 위치 레코드를 유지 관리 합니다. 그것은 곧 다음에 실행되어질 함수를 안다는 것이다. ( 그리고 실행 후에 지워질 것이다. ) 이것이 JavaScript에서 코드를 동기식으로 만드는 이유입니다.
식료품점 앞에 서있다고 생각해보자. 오직 다음 사람이 참석한 후에야 당신이 참석할 수 있는 것이다. 이것이 동기식이다.
이것은 "함수 호출 관리"가 의미하는 것입니다.
위 질문에 답을 아래 샘플 코드를 통해 답을 찾을수 있다. 아래 코드를 보자.
function firstFunction() {
console.log("Hello from firstFunction");
}
function secondFunction() {
firstFunction();
console.log("The end from secondFunction");
}
secondFunction();
위 코드가 동작하면서 어떤일이 일어났는가:
-
secondFunction()
이 실행이되면, 텅빈 스택프레임이 생성된다. 그것은 프로그램의 시작점인 (익명의) 메인이다. - 그런 다음
secondFunction()
이firstFunction()
을 호출하고 그것은 스택에 밀어넣어지게 된다. -
firstFunction()
는 리턴되고 "Hello from firstFunction"을 콘솔에 프린트 한다. -
firstFunction()
가 스택에서 튀어 나온다. - 이후 실행 순서가
secondFunction()
로 이동한다. -
secondFunction()
는 리턴되고 "The end from secondFunction"이 콘솔에 프린트 된다. -
secondFunction()
가 스택에서 튀어나오고 메모리는 깨끗해진다.
스택 오버플로우는 빠져나오지 못하는 재귀함수가 실행될때 발생하게 된다. 브라우저는 스택 에러를 던지기 전에 최대치의 스택을 가지고 있다.
아래 코드 예를 보자.
function callMyself() {
callMyself();
}
callMyself();
callMyself()
는 브라우저가 "Maximun call size exceeded" 라는 에러가 날때까지 수행하게 된다. 그리고 스택 오버플로우가 발생하게 된다.
콜 스택의 주요 특성들은 다음과 같다.
- 싱글 스레드라는 것은 한번에 한가지 일만 수행할 수가 있다는 말이다.
- 코드 실행은 동기적이다.
- 함수 실행은 스택 프레임을 생성하고 그것들은 임시 메모리를 차지한다.
- 콜 스택은 LIFO - Last In, First Out 데이터 구조를 지닌다.
원문 출처 : https://medium.freecodecamp.org/understanding-the-javascript-call-stack-861e41ae61d4