자바스크립트 엔진과 클로저 & this

세나정·2023년 6월 7일
0

JavaScript

목록 보기
6/11

⭐ 자바스크립트 엔진

  • 자바스크립트 엔진은 Memory Heap과 Call stack으로 구성되어 있음 (ex. 크롬 V8 Engine)

  • 자바스크립트는 싱글 스레드, 이 의미는 Call stack (호출 스택)이 한 개 라는 것
    -- Memory Heap : 메모리 할당이 일어나는 곳 (우리가 선언한 변수, 함수 등이 담겨 있음)
    -- Call Stack : 코드가 실행될 때 쌓이는 곳

  • 단일 콜 스택을 갖는다는 의미는 동기적으로 처리된다는 것을 의미

  • 비동기 요청을 처리하기 위해서는 자바스크립트를 실행하는 환경인 브라우저나 Node.js가 담당

⭐ 이벤트 루프

  • 자바스크립트는 싱글 스레드 기반 언어기 때문에 한번에 하나의 함수만 처리하지만 이벤트 루프를 기반한 동시성 모델을 지원

  • 이벤트 루프는 콜 스택과 콜백 큐의 상태를 체크하며 콜 스택이 빈 상태가 되면 콜백 큐의 첫번째 함수를 콜 스택에 넣음 이러한 행위의 반복이므로 루프라고 부르는 것이고 반복적인 행동은 틱(TicK)이라고 함

⭐ 콜백 큐

  • 콜백 큐에는 Task Queue와 Micro Queue가 있음
    -- Task Queue (태스크 큐, 매크로 큐)에는 Web API가 콜백함수를 콜백 큐에 넣은 setTimeout(), setInterval()과 UI렌더링, RequestAnimationFrame()이 담김
    -- Micro Queue (마이크로 큐)에는 비동기 호출을 넘겨 받아 태스크 큐보다 우선순위가 더 높은 Promise(then)과 mutationObserver, process.nextTick, async이 담김
    -- 따라서 이벤트 루프의 비동기 작업 처리 우선순위는 마이크로 큐 -> 애니메이션 프레임 -> 태스크 큐 순

  • 이벤트 루프는 우선적으로 마이크로 큐를 확인하고 그 안에 콜백 함수가 있다면 콜 스택으로 옮김 없다면 매크로 큐 (태스크 큐)를 확인 후 처리

Web API

  • 웹 API는 JS 엔진이 아님

  • 웹 API는 브라우저에서 제공하는 APi로 DOM, AJAX, TimeOut이 있음

  • 콜 스택 (호출 스택)에서 실행된 비동기 함수는 웹 API를 호출하고 웹 API는 콜백함수를 콜백 큐 (매크로 큐 (=Task Queue), 마이크로 큐)에 넣음

⭐ 실행 컨텍스트

  • 실행 컨텍스트는 자바스크립트 코드 실행환경 (변수 객체 (arguments, variable), 스코프 체인, this)에 대한 정보를 담고있는 객체

  • 실행 컨텍스트 구성요소
    -- Lexical Environment
    -- Variable Environment
    -- this 바인딩

  • 실행 컨텍스트는 전역 컨텍스트, 함수 컨텍스트 2가지 종류

  • 처음 자바스크립트 코드를 실행하는 순간 전역(글로벌) 컨텍스트가 생성되고 실행 컨텍스트에 쌓임

  • 전역 컨텍스트 생성 후 함수 컨텍스트는 함수를 호출할 때마다 실행 컨텍스트 스택에 쌓이고 호출이 끝나면 제거됨

  • 컨텍스트 생성 후 함수에 필요한 변수들은 변수 객체 안에서 값을 찾고 없으면 스코프 체인을 따라 올라가며 찾음

  • 함수 실행이 마무리 되면 해당 컨텍스트는 제거 (단, 클로저 제외) 모든 코드가 종료되면 전역 컨텍스트는 제거

⭐ 클로저 (closure)

  • 클로저는 자신이 선언 됐을 때의 렉시컬 스코프를 기억하여, 스코프 밖에서 호출 되어도 선언 됐을 때에 렉시컬 스코프에 접근할 수 있는 함수

  • 클로저는 자신이 선언될 때의 환경 (Lexical environment)을 기억하는 함수다라고 말할 수 있음
    -- "렉시컬(Lexical)" 이라는 명칭이 붙은 이유는 자바스크립트 컴파일러가 소스코드를 토큰(Token)으로 쪼개서 의미를 부여하는 렉싱(Lexing) 단계에 해당 스코프가 확정되기 때문

  • 몇몇 프로그래밍 언어에서는 클로저 구현이 불가능하거나 특수한 방식으로 함수를 작성해야 클로저를 만들 수 있지만, 자바스크립트에서는 모든 함수가 자연스럽게 클로저가 됨

  • 자바스크립트의 함수는 숨김 프로퍼티인 [[Environment]]를 이용해 자신이 어디서 만들어졌는지를 기억, 함수 본문에서 [[Environment]]를 사용해 외부 변수에 접근

  • 클로저를 사용하는 이유
    -- 정보를 은닉하기 위해
    -- 전역변수 사용을 억제하기 위해
    -- 현재 상태를 기억하고 변경된 최신 상태를 유지 하기 위해 (useState)

클로저와 커링

  • 커링은 함수에 n개의 인자를 받는 대신, n개의 클로저 함수를 만들어 각각 인자를 받게하는 방법

  • 커링은 클로저와 별개인 무언가가 아니라 클로저의 특징을 이용한 기법, 클로저의 외부 함수 변수의 값을 고정할 수 있음에 유용

⭐ 자바스크립트에서 this 바인딩

  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수

  • 자바스크립트 일반 함수, 콜백함수의 this는 어디에 선언 되었든 전역 객체를 바인딩
    -- 즉, 어디서 호출 했냐에 따라 결정됨
    -- 브라우저에서는 window, node에서는 global 근데 요즘은 globalThis로 통합
    -- 엄격 모드 (use strict)에서는 undefined를 반환

  • 객체 메서드 내부의 this는 메서드를 소유한 객체, 즉 해당 메서드를 호출한 객체에 바인딩

  • 화살표 함수의 this는 언제나 자신이 선언 됐을 때의 this, 이를 렉시컬 this라고 함

⭐ bind, call, apply

  • 바인딩이란 식별자와 값을 연결하는 과정
  • this 바인딩은 this와 this가 가리킬 객체를 바인딩 하는 것
  • 세 가지 모두 this를 바인딩 하기 위한 방법
  • bind는 함수를 호출하는 것이 아닌 새로운 함수를 선언하는 것 그래서 사용하려면 바로 ( ) 붙여서 사용해야함
  • call은 this를 바인딩하면서 함수를 호출, 두번째 인자를 apply와 다르게 한 개씩 넘기는 것
  • apply는 this를 바인딩하면서 함수를 출하는 것, 두번째 인자가 arguments(유사 배열)임

가비지 컬렉터의 역할

  • 메모리 할당을 추적하고 할당된 메모리 영역이 필요하지 않을 떈 판단해서 회수하는 것
  • 자바스크립트, 파이썬, 자바는 GC가 존재하지만 C나 C++등 존재하지 않아 수동으로 메모리 관리하기 때문에 구현하여 사용해야함

⭐ 자바스크립트 엔진이 코드를 실행하는 과정

자바스크립트를 실행하기 위해서는 자바스크립트 엕빈이 필요하고 웹 브라우저는 자바스크립트 엔진을 내장하고 있음 브라우저마다 엔진의 종류는 다르지만 코드를 실행하는 방식은 비슷함

  • 소스코드를 만나면 파싱하여 AST (Abstract Syntax Tree)로 변환

  • 인터프리터는 AST를 기반으로 바이트코드를 생성

  • 인터프리터가 바이트 코드를 실행시, 자주 사용되는 함수 및 타입 정보등이 있는 프로파일링 데이터와 같이 최적화 컴파일러에게 보냄

  • 최적화 컴파일러는 프로파일링 데이터를 기반으로 최적화된 코드를 생성

  • 하지만 프로파일링 데이터 중 잘못된 부분이 있다면 최적화 해제를 하고 다시 바이트 코드를 실행해서 이전 동작을 반복

profile
압도적인 인풋을 넣는다면 불가능한 것은 없다. 🔥

0개의 댓글