본문 바로가기

언어/JavaScript

자바스크립트는 어떻게 작동하는가? - 브라우저, 자바스크립트의 동작원리

728x90

안녕하세요!! 숯 같은 개발자 엄탱입니다!!

즐거운 추석 다들 잘 보내셨나요!?
이 글을 포스팅할 때쯤은 추석이 끝나는 날이겠네요....

저는 이상하게 쉬는 날에 혈압? 같은 게 올라와서 뒷골이 당기는데 여러분들도 꼭 건강 잘 챙기세요:)

 

이 포스팅은 자바스크립트에서 제일 중요하다고 생각하는 주제 중에 하나라고 생각합니다!

그래서 제가 이번에 정말 정말 정말 너무 늦게 포스팅을 하는 것 같아요.

이번 주제가 자바스크립트의 동작원리이다 보니 더 정확하게 알고 싶은 마음에 더 자세하고 깊게 공부를 하다 보니 이상하게 점점 더 글이 안 써지더라고요.. 네.. 맞습니다.. 변명이었습니다...

 

그럼 변명도 했으니 바로 시작하도록 하겠습니다.

 

 

우선 자바스크립트의 동작 원리를 알기 전에 자바스크립트는 어떤 언어 일지 알아보는 게 좋습니다!

 

자바스크립트란?

자바스크립트는 싱글 스레드 언어이며 동기적 언어입니다.

물론 자바스크립트는 비동기 기반으로 동작하는 언어라고 하는 말도 맞습니다!! 자바스크립트는 비동기 동작이 없으면 굉장히 사용자에게 느린 동작을 제공할 수밖에 없습니다.

 

자바스크립트는 어떤 언어인지 자세히 알고 싶으면 제가 따로 포스팅해놓았습니다! !!!링크!!!를 클릭해주세요.

 

자바스크립트의 동작 원리

자바스크립트야 너는 도대체 어떻게 동작하는 거니!??

자바스크립트의 동작 원리를 알기 위해서는 브라우저의 엔진을 들여다봐야 합니다. 뭐 사실상 브라우저의 원리라고 할 수 있습니다.

엔진을 들여다보고는 싶은데… 컴퓨터처럼 다 뜯어보고 알아볼 수도 없고 어떡하면 좋을까요?? 하시는 분들을 위해!! 유명한 사진 하나를 들고 왔습니다! 자바스크립트를 깊게 공부하기 시작하셨다면 한 번쯤은 꼭 봤을 법한 사진입니다!

아래 사진은 구글의 V8엔진을 간단히 표시한 모습입니다. 참고로 V8엔진은 크롬과, 노드js에서 사용합니다.

 

 

V8엔진은 크게 두 부분으로 구성됩니다.

  • 메모리 힙(Memory Heap)
    • 참조 타입(객체 등) 데이터를 저장합니다.
    • 메모리 할당이 일어나는 장소입니다.
  • 콜 스택(Call Stack)
    • 원시 타입 데이터를 저장
    • 실행 컨텍스트(Execution Context)를 통해 다음과 같은 일을 수행합니다.
      • 변수 식별자(이름) 저장
      • 스코프 체인 및 this 관리
      • 코드 실행 순서 관리 등을 수행

V8 엔진을 보시면 콜 스택(Call Stack)이 하나인 게 보이시죠?? 자바스크립트는 싱글 스레드이기 때문에 콜 스택이 하나뿐인 것입니다.

 

 

여기서 잠깐!!!
아니 근데 도대체 콜 스택은 데이터도 저장하고 스택도 저장하고 어떻게 동작하는 거야????라고 생각하시는 분들이 혹시 있으실까요??
저도 콜 스택의 이 부분에 대해서 알고 싶어서 공부를 자세히 하다가 포스팅이 더 늦어졌습니다. 
이 부분은 해당 링크에 들어가셔서 확인해보시면 동작원리를 자세히 알 수 있을 거예요!!

 

 

하지만 자바스크립트는 메모리 힙, 콜 스택 두 가지 가지고는 원활한 동작을 하기에는 부족합니다!

원활한 동작을 위해서 아래와 같이 몇 가지 런타임 환경이 필요합니다.

  • 브라우저의 Web APIs 혹은 Node.js의 libuv
  • 이벤트 루프(Event Loop)
  • 콜백 큐(Callback Queue)

 

브라우저의 Web APIs

흔히 알고 있는 ajax, dom event, setTimeout 같은 함수들은 자바스크립트 엔진이 아닌 Web APIs에서 제공하고 있다는 사실!!

더 많은 API를 확인하고 각종 브라우저에서 제공하는지 확인하고 싶으시다면 Web API 를 참고해주세요. (참고로, 자바스크립트 자체는 싱글 스레드지만 network, timer, dom event 같은 경우는 브라우저에서 멀티스레드로 돌아갑니다.)

 

이벤트 루프

이벤트 루프는 콜 스택과 콜백 큐를 계속 감시하고 있다가 콜백 큐에 콜백 함수가 쌓이게 되면 콜 스택으로 올려 보내는 역할을 합니다. 단, 콜 스택이 비워져 있는 경우에만 콜 스택을 올려 보냅니다.

 

콜백 큐

콜백 큐는 Web API에서 동작이 끝난 함수들의 콜백 함수들이 대기하고 있는 대기실입니다.

또한 콜백 큐는 선입선출의 구조(FIFO)를 띄고 있으며, 콜백 큐의 종류는 실제로는 더 다양하게 존재합니다. 콜백 큐의 종류에 따라 실행 스택으로 옮겨지는 우선순위도 다른데요.
콜백 큐를 자세히 설명하자면 내용이 다른 주제로 빠지게 되어 여기서는 다루지 않겠습니다.

 

 

총 동작 순서

자바스크립트 동작 원리의 꽃인 동작 순서를 살펴보겠습니다. 직접 눈으로 보고 싶으신 분들은 링크를 클릭해주세요.

function zero(){
    console.log('hi zero');
}

function two() {
    console.log('hi two');
}

zero();

setTimeout(function one() {
	console.log('hi one');
}, 500);

two();

 

위의 코드를 가지고 동작원리를 설명드리겠습니다!

제가 직접 피피티로 만든 거라 약간 조잡할 수 있습니다 :)

 

 

위의 그림을 순서대로 설명을 드리겠습니다.

 

1. 우선 가장 먼저 zero()가 콜 스택에 쌓이게 됩니다.

2. zero()가 콜 스택에 쌓이고 zero() 함수 안에 코드들을 위에서 아래까지 순서대로 콜 스택에 쌓이게 됩니다. 위의 그림에서는 console.log('hi zero')가 zero() 위에 스택이 쌓이게 됩니다.

3. 그 후에는 console.log('hi zero')가 실행이 되어 hi zero가 출력되고  console.log('hi zero')가 스택에서 제거됩니다.

4. 마지막으로 zero() 안의 코드가 다 동작하고 zero()가 스택에서 제거됩니다.

 

 

 

 

5. 그다음으로 zero() 다음 코드인 setTimeout() 함수가 스택에 쌓이게 됩니다.

6. setTimeout() 함수는 webAPI에서 제공하는 함수로서 해당 함수는 WebAPIs로 넘어가서 setTimeout의 콜백 함수인 one() 함수가 0.5초간 Web APIs에 머무르게 됩니다.

 

 

 

 

7. 그다음에는 two() 함수가 콜 스택에 쌓이게 됩니다. 

 

(번외. 7번의 그림에서 보면 two()가 끝나기 전에 Web APIs에 있는 one() 함수가 0.5초 후에 콜백 큐로 넘어간 걸로 보이는데 사실상 two() 함수 0.5초보다 빠르게 동작하기 때문에, two() 함수가 끝나기 전에는 one() 함수가 콜백 큐로 넘어가지 않습니다. 단지 one()함수가 콜백 큐로 넘어가는 게 콜 스택과는 다르게 움직이는 걸 보여드리고 싶어 위와 같이 만들어봤습니다.)

 

8. 그 후에는 two() 함수의 코드 순으로 스택에 쌓이게 되어 console.log가 two() 함수 위에 스택이 쌓이게 됩니다.

9. 마찬가지로 hi two가 출력되고 console.log() 스택이 콜 스택에서 제거됩니다.

10. 마지막으로 two() 함수가 스택에서 제거가 됩니다.

 

 

 

11. 콜 스택이 전부 비워지고 나서 콜백 큐에 있던 one() 함수가 이벤트 루프에 의해 콜 스택에 스택이 쌓이게 됩니다.

12 ~ 14. 그 뒤로는 로그가 스택이 쌓이고 로그가 출력 후 스택에서 제거된 후에 마지막으로 one() 함수가 스택에서 제거되고 마무리됩니다.

 

 

 

자바스크립트 동작원리에 대해 준비한 내용은 여기까지입니다.

잘못된 내용, 부족한 부분이 보이시면 댓글 남겨주시면 감사하겠습니다:)

 

728x90