안녕하세요

자바스크립트 프론트엔드 지식 본문

카테고리 없음

자바스크립트 프론트엔드 지식

sakuraop 2023. 11. 11. 15:16

자바스크립트란
HTML, CSS와 함께 사용되어 웹을 동적으로 만들고 상호작용할 수 있도록 하는 언어
웹 브라우저에서 해석되는 인터프리터 언어
객체기반의 스크립트 언어

싱글 스레드 언어로 blocking이 발생
이벤트 기반으로 사용자와 상호작용

비동기 작업을 통해 서버와 통신

 

스크립트 언어란
소스 코드를 *컴파일 하지 않고 실행할 수 있는 프로그래밍 언어
컴파일 과정이 없어 프로그램을 실행시켜야 오류를 알 수 있다.
프로그램을 실행할 때마다 매번 같은 코드를 번역해야 하기 때문에 컴파일 언어에 비해 프로그램의 실행 속도가 느리다

 

*컴파일이란 기계가 이해할 수 있는 2진 데이터로 변경하는 작업으로, 그 결과 실행 파일이 만들어진다.

컴파일 언어란
한 번 컴파일을 하면 이후로는 기계어를 읽어들이기 때문에 실행속도가 빠르다.
기계어로 프로그램이 실행되기 때문에 소스코드가 유출되기 어렵다.
운영체제에 따라 기계어가 다르기 때문에 작업을 다르게 해주어야 한다.

 

실행 컨텍스트란
코드가 실행될 때 생성되는 환경으로 변수, 함수, 스코프 등이 포함된다.
스택 자료구조로 관리되며 함수를 호출할 때마다 새로운 실행 컨텍스트를 생성하여 스택에 추가되고, 반환될 때 스택에서 제거된다.

렉시컬 환경이란
변수와 함수 선언이 어디에서 참조되고 어떻게 중첩되는지를 기록하는 환경을 가리킨다.
스코프 체인을 통해서 코드가 진행되고 있는 렉시컬 환경에서 외부 렉시컬 환경의 변수나 함수를 참조할 수 있게 된다.

 

동기와 비동기
자바스크립트는 싱글 스레드 언어로 동기적으로 동작한다.
동기 작업은 브라우저에서 또는 Node.js에서는 V8 엔진이 코드를 인터프리팅하는 런타임 환경에서 실행된다.
함수를 호출하면 인터프리터가 콜 스택에 해당 함수를 담는 형식이다.
따라서 한번에 한개의 작업만 실행하는 blocking이 발생한다.
이러한 실행 지연을 비동기 처리로 해결할 수 있다.
비동기 객체는 Web API에 저장되어 있다가 실행 시점에 도달하면 *콜백 큐로 보내진다.
이벤트 루프는 콜 스택과 콜백 큐 사이에서 콜 스택이 비워지면 콜백 큐의 함수들을 순서대로 콜 스택으로 넘겨준다
재귀같은 동작을 잘못 사용하거나 너무 많은 작업이 콜 스택에 할당되면 스택 오버플로우 에러가 발생한다.

*콜백 큐로 보내지는 순서
1. Promise와 관련된 작업 (Micro task Queue)
2. 애니메이션 관련 작업
3. 이벤트 핸들러, HTTP요청, setTimeout, DOM 조작과 같은 작업

콜 스택과 메모리 힙 
콜 스택에는 원시타입이 할당되고, 객체들은 힙 메모리에 할당된다. 
콜 스택은 객체 자체를 지니고 있는 것이 아니라 힙 메모리의 객체를 참조하는 주소를 지니고 있다.
데이터 변경 유무는 힙 메모리의 값의 변경이 아니라 콜 스택 참조값의 변경에 따라 결정된다.
콜 스택에서 더 이상 참조하지 않는 메모리는 가비지 컬렉터에서 메모리 제거 대상이 된다.

가비지 컬렉터는
더이상 참조가 되지 않는 객체 데이터를 힙 메모리에서 제거한다.
대부분의 경우 메모리 해제를 직접 수행하지 않아도 브라우저에서 자동으로 관리를 해주지만, 모든 메모리가 자동으로 해제되는 것이 아니다.
전역 변수, 이벤트 리스너, setInterval과 같은 경우에는 직접 메모리를 해제해주지 않으면 계속해서 힙 메모리에 쌓이게 된다.

가상 DOM이란
실제 DOM의 element를 조작하여 상태를 업데이트 시키는 것은 모든 DOM을 새롭게 업데이트 하기 때문에 메모리 낭비가 심하다.
이 문제를 해결하기 위해 가상 DOM을 이용한다.
가상 DOM은 실제 DOM의 구조를 복제한 가벼운 자바스크립트 객체이다.
상태 업데이트가 일어나면 이전 DOM과 현재 상태를 비교하여 변경사항을 메모리에 기록한다.
변경된 부분에 대한 정보를 바탕으로 실제 DOM의 변경된 부분만 업데이트하여 상태를 일치시킨다.

 

setState로 state를 변경하는 이유
상태의 불변성을 유지하기 위해서. (이게 뭔 말이냐면)
가상 DOM으로 생성된 컴포넌트가 업데이트 되는 조건은 state에 변화가 있을 때다.

state를 직접 변경하는 작업은 참조하고 있는 객체의 데이터 변화를 감지하지 못한다.

변화를 감지 못하므로 리렌더링을 하지 않게 되어 실제 데이터와 화면상의 데이터가 달라진다.
성능과도 연관이 있다.

매 setState마다 리렌더링을 하는 것은 불필요한 리렌더링을 너무 자주 유발한다.
따라서, setState는 비동기로 동작하여 동기적인 코드를 모두 처리한 뒤 setState끼리 모아서(batching) 상태 변화를 감지한다.
이렇게 함으로써 모든 상태 변화에 대해 각각 렌더링을 수행하지 않고 최종적인 상태들을 가지고 리렌더링을 한 번만 하도록 한다.
이러한 목적을 지키기 위해서라도 어느 시점에 state가 변하는지 기본적인 동작 원리를 숙지하여 불필요한 리렌더링을 유발하지 않도록 주의해야 한다.