JavaScript


1. JavaScript 엔진

  • Call Stack과 Memory Heap으로 이루어짐.
    • Call stack: 원시 타입 데이터 저장, 코드 실행 순서 관리 LIFO
    • Memory Heap: 객체 등의 참조타입의 데이터가 저장됨. 메모리 할당이 일어남.
  • 단일 호출 스택을 사용하기에 싱글 스레드다.
  • 동기적 함수들은 Call Stack으로 처리. 그러나 Promise,DOM과 같은 비동기 함수는..?

2. Javscript의 비동기 함수 처리

Web API

  • 웹 브라우저에서 제공 하는 API로 DOM, Timeout,AJAX등이 있음.
  • 비동기 함수를 처리하고, 그동안 Call Stack은 나머지 동기 함수들을 처리함.

Event Loop

  • 스레드 안에 있는 코드를 스케줄링하고 실행시켜 Javscript엔진(single thread)을 멀티 스레드인 구동 환경과 연결시켜주는 역할.
  • Call Stack에 함수가 존재하지 않을 때, 우선 순위에 따라 FIFO로 task queue에 있는 비동기 함수를 Call Stack에 넣음.

task Queue

  • 비동기 함수를 보관하는 장소. Event Loop에서 함수 꺼내기 전까지는 계속 Queue방식으로 보관함.
    1. Macrotask
      • MicroTask를 싹 다 비운 뒤에 MacroTask를 처리함.
    2. Microtask
      • promise로 만듦. then, cathc, finally, await 핸들러

https://www.jsv9000.app/

위 링크에서 작동 방식을 보면 이해가 빨리 된다.

Process and Thread


예시

프로그램: 프로젝트 기획서

Process: 프로젝트 진행 중.

프로젝트를 진행하려면 회사(OS)에서 자원, 시간을 할당 받아야 함. (메모리에 올라감)

Thread: 홍보팀, 사업팀 마케팅 팀 등 프로젝트를 위해 동시에 일을 진행함. 할당된 자원을 같이 공유함.

프로그램: 브랜드 설립, 그 자체

Process: 가게를 차려 운영함.

가게를 차리려면 나라(OS)에서 땅에 인허가를 내줌(메모리에 올라감, 작업 영역 할당). 이 자리에서 영업하세요

Thread: 가게에서 영업을 위해 동시에 일을 진행함. 고객 응대, 매대 정리, 음식 만들기 등이 동시에 돌아감. 이때 가게 안의 자원을 같이 공유함. 다만, 독자 행동이 가능함.

Process

출처: https://gmlwjd9405.github.io/

  • 프로그램이 돌아가고 있는 상태.
    • 정적인 코드 덩어리인 프로그램을 실행시켜 정적인 프로그램이 된 상태.
    • 실행하기 위해선 OS가 메모리 공간을 할당해줘야 실행 가능.
  • 프로그램(코드 덩어리)이 실행될 때 즉시 CPU로 부터 할당받는 자원 영역, 자원을 할당받은 작업의 단위
  • 프로그램이 메모리에 올라와, 운영체제로부터 자원을 할당받고, 프로그램이 연속적으로 실행되고 있는 상태.
  • 특징

    1. 각각 독립된 메모리 영역 (Code, Data, Stack, Heap)을 할당 받음.

      1. 메모리의 구조

        1. 정적 영역
          1. Code: 명령 실행하는 코드, 명령어
          2. Data: 변수(Static, Global)
            1. 초기화안된 global, static 변수(bss)
            2. 초기화된 global, static 변수(.data)
            3. (.rodata) 섹션
        2. 동적 영역
          1. Heap: 동적 메모리 영역, 개발자가 관리하여 할당 해제 가능 (자바스크립트는 참조 타입 저장)
            • 개발자가 할당 후 수동으로 해제하지 않으면 누수 발생.
          2. Stack: 일시적인 데이터 (반환 값, 지역 변수 할당 및 해제, 매개 변수, 함수 호출 등)
            1. 자바스크립트는 원시타입을 콜스택에 저장함.

        출처: https://gmlwjd9405.github.io/

    2. 다른 프로세스에 접근하려면 IPC,LPC등 을 이용해야 함.

Thread

출처: https://www.tcpschool.com/

  • 정의 :
    • 프로세스 내에서 실행되는 여러 흐름의 단위
    • 하나의 프로세스에서 자원을 공유하면서 일련의 과정을 동시에 여러 개 실행시킬 수 있는 것.
    • 햄버거라는 프로세스 안에 스레드 1: 패티를 굽지, 스레드2, 빵을 굽기를 동시에 하는 것.
    • Code, Data, Heap을 공유하여 공통된 자원을 사용함. 다만, 레지스터, Stack,은 따로 갖고 있음.
      • 따라서 독립적인 함수 호출 → 독립적인 실행 흐름을 각 Thread가 가질 수 있음.
  • 특징
    1. 프로세스 내 여러 개 존재 가능
    2. 어떤 스레드가 자원을 변경하면, 다른 이웃 스레드가 변경 결과를 즉시 볼 수 있음.

Hoisting and Closer


JavaScript 실행 단계

  1. 컴파일: 변수, 함수 선언을 코드가 실행되기 전에 메모리에 등록
  2. 실행: 코드가 순차적으로 실행되며 실제로 변수, 함수를 사용

Hoisting

  • Hoist:끌어올리다.
  • 코드가 실행 되기 전, 필요한 메모리 공간을 확보하여 예기치 못한 오류를 막기 위해 실행.

변수

  • scope단위로 변수, 함수의 선언과 할당이 분리되어 식별자가 우선 선언된 것 같은 현상.
  • 왜냐하면… Javscript 엔진 구동시 선언이 최우선으로 해석되기 때문이다. 할당은 실제 코드 실행 시 동작함.
  • var: 변수 객체 등록 후 메모리 할당(undifined로 초기화)까지 호이스팅 됨. 즉, 초기화나 할당 전에도 이미 undifined로 초기화 되어 메모리가 할당되어있기에 접근 가능.
  • let, const: 변수 객체 등록 까지만 진행됨. 따라서 선언 지점 전에 참조하면 오류 발생.
    • TDZ(Temporal Dead Zone): 스코프 시작 지점부터 초기화 지점까지의 구간

함수

  • 함수 선언식: 함수 식까지 호이스팅 됨
funciton example(){
	console.log('함수 선언식' )
	}
  • 함수 표현식: var example 변수는 호이스팅 되지만 함수는 할당되기 전까지 참조 불가.
var example = function () {
  console.log("함수 표현식");
};

클로저

  • 함수가 함수를 반환할 때, 그 반환되는 함수가 자신을 둘러싼 메모리 환경도 가지고 반환하는 것. 따라서 함수가 스코프 밖에서 실행될 때에도 접근 가능하다.
  • 전역 변수의 남용을 막고 캡슐화, 은닉화를 자바스크립트로 구현하기 위해 존재함.

선언 할당이 분리됨. 선언은 최상단. 할당은 실행될 때 일어남.

실행 컨텍스트는 정보를 모아놓는 곳. 설정하는 과정에서 자스는 모든 변수,함수 선언을 메모리 공간에 넣어놓음.

어떤 변수, 함수가 있는지 알고 실행함.

자바도 실행 컨텍스트 있음. 사용할 수 있는 메모리 공간의 위치라고 함.

메모리에 접근할 수 있는 실행 컨텍스트를 갖고 있따.

자바는 왜 호이스팅을 독특하게 할까요

순차적으로 하면 이렇게 안해도 되는데 .

스코프와 클로저

클로저: 함수가 선언된 환경의 스코프를 기억하여, 함수가 스코프 밖에서 실행될 때에도 스코프에 접근할 수 있게 함.

내부함수는 외부함수의 지역변수에 접근 할 수 있는데 외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근 할 수 있다.

내부 함수에서 외부함수에서 선언된 변수를 사용한다면, 내부함수는 클로저가 된다.