자바스크립트 동작원리

jaehan·2023년 5월 19일
0

JavaScript

목록 보기
29/33

그래도 프론트엔드 공부한다는 사람인데 자바스크립트 동작원리를 제대로 모르고 있다고 생각이 들어서 한번 공부해봤다.

자바스크립트 동작원리

자바스크립트를 실행하기 위해서는 자바스크립트 엔진이 필요하다

대표적인 엔진으로는 google에서만든 V8엔진이다.

📌 엔진은 Memory Heap, Call Stack으로 구성된다.

  • Memory Heap에는 메모리 할당이 발생한다.
  • Call Stack은 코드 실행에 따라 스택이 하나씩 쌓인다.

아래 사진은 v8엔진의 간단한 그림이다.

❓ 여기서 궁금한 점이 생겼었는데 렉시컬 환경의 환경레코드에는 실행컨텍스트의 값이 저장되어있다고 알고 있었는데 그럼 걔네들은 어디에 있는걸까

❗️ 답은 우선 자바스크립트는 원시값과 객체로 이루어져 있게 되는데 객체는 크기가 동적으로 변하기 때문에 힙 영역에 존재하게 된다.
또한 원시값은 콜 스택 내부의 메모리 영역에 존재하게 된다.

그리고 환경 레코드또한 실행컨텍스트의 일부분이기 때문에 콜 스택에 존재하게 되고
이 환경 레코드에는 원시값이 저장되어 있는 주소 값이 저장되고, 객체의 주소를 알고있는 메모리 공간의 주소가 저장되는 것이라는걸 알게 되었다.

Call Stack 동작 원리

예시는 블로그에 잘나와있어서 가져와 봤다.

function multiply(x, y) {
    return x * y;
}
function printSquare(x) {
    var s = multiply(x, x);
    console.log(s);
}
printSquare(5);

스텝별로 확인해보면

  1. printSquare(5)를 Call Stack에 push

  2. printSquare(5)호출 -> 내부의 multiply(x, x)를 Call Stack에 push
    2-1. multiply(5, 5) 실행해서 var s에 값 할당. multiply Call Stack에서 pop

  3. console.log(s) Call Stack에 push
    3-1. console.log(10) 실행후 Call Stack에서 pop

  4. printSquare(5) 끝났으니 Call Stack에서 pop

이렇게 동작하는걸 확인할 수 있다.

간단하게 정리해 보면 코드에서 객체(변수, 함수)등은Heap Memory에 저장되고

실행할 문장을 Call Stack에 push하고 Heap Memory의 값들을 참조해서 실행하고, 끝나면 pop하고의 과정을 반복한다.

❓ 위 예시만 보면 자바스크립트는 동기적으로만 동작하나? 라는 생각이 들 수 도 있다.

그건또 아니다.

생각해보면 자바스크립트에서 setTimeOut()을 사용해 본적이 있을텐데

위의 예시를 보면 call Stack이 하나기 때문에 1, 2초쉬고 settimeout, 2가 출력될거라 생각했지만 1, 2, 2초쉬고 settimeout이 출력된다.

💡 이건 자바스크립트엔진 외에 비동기적으로 작업해주는게 또 있는것이다.

그게바로 Event Loop와 Callback Queue이다.

Event Loop & Callback Queue

이 개념에 대해 알아보기 전에 기본 개념을 알아보자면

Web API란

웹 브라우저 혹은 node js 같은 자바스크립트 런타임에서 지원해주는 API이다.
예를 들어 setTimeOut(), AJAX 같은 애들이다.

런타임이란

런타임은 자바스크립트가 구동되는 환경이다.

나는 컴파일 처럼 코드가 실행되는 시간이라 생각했다. 타임이 들어가서

근데 그냥 환경이라고 한다. 따라서 Nodejs나 브라우저들을 런타임 이라고 하는거다.

📌 Web API나 Event Loop & Callback Queue를 런타임에서 제공해준다고 생각하면 된다.

❗️ 이제 기본 개념들을 알게 되었으니 아래와 같은 자바스크립트 동작 구조가 만들어 졌다.

이제 Event Loop 와 Callback Queue에 대해 알아보자면.

아까 봤던 예제로 동작을 예상해 보면

  1. console.log("1")이 stack에 push 된다.
    1-1. console.log("1") 출력후 pop
  2. setTimeout()이 stack에 push됨
    2-1. 비동기 함수인걸 확인하면 Web API가 처리하도록 보냄
  3. console.log("2")이 stack에 push 된다.
    3-1. console.log("2") 출력후 pop
  4. 2초 지나면 setTimeout 내부의 callback 함수(console.log("settimeout"))가 Callback Queue에 들어감.
    4-1. Event Loop가 Call Stack이 비었는지 확인후 비었으면 Callback Queue의 값 pop해서 Call Stack에 push.
  5. console.log("settimeout") 출력후 stack에서 pop

그림으로 예제를 확인하고 싶으면 아래 참고한 블로그에 가면 있다.

추가

또 이벤트 루프는 우선순위를 따져서 콜 스택으로 보낸다

마이크로태스크 큐, 애니메이트 프레임, 태스크 큐 순으로 우선순위를 가진다.

간단히 설명하면 태스크 큐는 콜백 큐안에 있고 나머지는 따로있다.

그래서 이벤트 루프가 콜 스택이 비면

마이크로태스크 큐 확인 -> 아무것도 없으면

애니메이트 프레임 확인 -> 아무것도 없으면

태스크 큐(콜백 큐)의 값을 순서대로 넣음

의 과정이라고 생각하면 된다.

https://tristy.tistory.com/51

0개의 댓글