▣ 호이스팅(hoisting)?
var name = 'global name';
function callName() {
console.log(name); // ?
var name = 'local name';
};
callName();
위 예제 코드에서 출력되는 변수 name의 값은 'global name' 일 것 같지만, 'local name' 이다.
특정 스코프 안에서 선언된 변수(name)는 코드에 적힌 순서와 상관없이 "최상단에서 선언한 것처럼" 끌어올려진다. 이것을 #호이스팅#이라고 한다.
var, let, const, function, funtion*, class 키워드를 사용해서 선언하는 모든 식별자(변수, 함수, 클래스 등)는 호이스팅 된다.
그러나 var와 달리 let, const는 호이스팅이 되지 않는 것처럼 보인다.
왜냐하면 래퍼런스 오류가 뜨기 때문입니다.
밑의 예처럼.,
pi; // throws `ReferenceError` //밑에서 선언하고 위에서 사용한 경우
const pi = 3.14;
이때 등장하는 개념이 TDZ입니다.
▣ TDZ ?
TDZ 란 Temporal Dead Zone 의 약자로 우리 말로 번역하면 일시적 사각지대라는 의미이며, 선언 전에 변수를 사용하는 것을 비 허용하는 개념상의 공간이라고 이해하면 쉽다. [스코프 시작 ~ 초기화 시작 사이의 구간]
변수선언 3단계
$ 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록한다.
-> 스코프가 참조하는 대상
[T -- D-- Z --]
$ 초기화 단계(Initialization phase) : 실행 컨텍스트에 존재하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만든다.
-> undefined로 초기화된다.
$ 할당 단계(Assignment phase) : 사용자가 undefined로 초기화된 메모리에 다른 값을 할당한다.
▣ 이해 하기
왜 var 와 달리 const, let 은 래퍼런스 오류가 떠서 호이스팅이 발생하지 않는 것처럼 보이는가.
바로 TDZ에 있는 값에 접근하게 되어서 입니다.
먼저 선언형식에 따른 초기화 차이를 보자면,
변수 선언 형식에 따른 초기화 차이
var : 호이스팅 시 undefined로 변수를 초기화
function : 선언된 위치와 상관없이 동일하게 호출
let, const : 호이스팅 시 변수를 초기화하지 않음.
그래서 호이스팅시 변수를 초기화하는 var와 달리 let const는 초기화단계 이전이기 때문에,
해당 변수들이 호이스팅되어 메모리에 저장은 되어있지만, 직접적인 선언 전까지 해당 데이터들에 접근할 수 없는 TDZ 때문에 오류가 뜹니다.
요약: TDZ는 선언 전에 변수를 사용하는 것을 허용하지 않는다.
let과 const는 호이스팅 되지 않는 것이 아니라 선언 전에 변수를 사용하는 것을 허용하지 않는 tdz때문에 그렇게 안보이는 것.
var 중복선언과 재할당으로 문제가 있어 권장하지 않습니다.
- Parsing
브라우저가 페이지를 렌더링하려면 가장 먼저 받아온 HTML 파일을 해석해야한다. Parsing 단계는 HTML 파일을 해석하여 DOM(Document Object Model) Tree를 구성하는 단계이다.
파싱 중 HTML에 CSS가 포함되어 있다면 CSSOM(CSS Object Model) Tree 구성 작업도 함께 진행한다.- Style
Style 단계에서는 Parsing 단계에서 생성된 DOM Tree와 CSSOM Tree를 매칭시켜서 Render Tree를 구성한다. Render Tree는 실제로 화면에 그려질 Tree이다.
예를 들면 Render Tree를 구성할때 visibility: hidden은 요소가 공간을 차지하고, 보이지만 않기 때문에 Render Tree에 포함이 되지만, display: none 의 경우 Render Tree에서 제외된다.- Layout
Layout 단계에서는 Render Tree를 화면에 어떻게 배치해야 할 것인지 노드의 정확한 위치와 크기를 계산한다.
루트부터 노드를 순회하면서 노드의 정확한 크기와 위치를 계산하고 Render Tree에 반영한다. 만약 크기 값을 %로 지정하였다면, Layout 단계에서 % 값을 계산해서 픽셀 단위로 변환한다.- Paint
Paint 단계에서는 Layout 단계에서 계산된 값을 이용해 Render Tree의 각 노드를 화면상의 실제 픽셀로 변환한다. 이때 픽셀로 변환된 결과는 하나의 레이어가 아니라 여러 개의 레이어로 관리된다.
당연한 말이지만 스타일이 복잡할수록 Paint 시간도 늘어난다. 예를 들어, 단색 배경의 경우 시간과 작업이 적게 필요하지만, 그림자 효과는 시간과 작업이 더 많이 필요하다.- Composite
Composite 단계에서는 Paint 단계에서 생성된 레이어를 합성하여 실제 화면에 나타낸다. 우리는 화면에서 웹 페이지를 볼 수 있다.
과거에는 클래스형 컴포넌트를 많이 사용했지만
2019년 v16.8 부터 함수형 컴포넌트에 리액트 훅(hook)을 지원해 주어서
현재는 공식 문서에서도 함수형 컴포넌트와 훅(hook)을 함께 사용할 것을 권장하고 있다.
Stack?은 프링글스입니다. FILO(First In Last Out.)후입선출
같은 구조와 크기의 자료를 정해진 방향으로만 쌓을수 있고,
top으로 정한 곳을 통해서만 접근할 수 있다.
삽입하는 연산을 'push' , top을 통한 삭제하는 연산을 'pop'이라고 한다.
💫 스택의 활용 예시
- 스택의 특징인 후입선출(LIFO)을 활용하여 여러 분야에서 활용 가능하다.
- 웹 브라우저 방문기록 (뒤로 가기) : 가장 나중에 열린 페이지부터 다시 보여준다.
- 역순 문자열 만들기 : 가장 나중에 입력된 문자부터 출력한다.
- 실행 취소 (undo) : 가장 나중에 실행된 것부터 실행을 취소한다.
- 후위 표기법 계산
- 수식의 괄호 검사 (연산자 우선순위 표현을 위한 괄호 검사)
Queue?는 맛집 줄 입니다. FIFO(First In First Out.)선입선출
정해진 한 곳(top)을 통해서 삽입, 삭제가 이루어지는 스택과는 달리!!
큐는 한쪽 끝에서 삽입 작업이, 다른 쪽 끝에서 삭제 작업이 양쪽으로 이루어진다.
이때 삭제연산만 수행되는 곳을 프론트(front), 삽입연산만 이루어지는 곳을 리어(rear)로 정하여
각각의 연산작업만 수행된다. 이때, 큐의 리어에서 이루어지는 삽입연산을 인큐(enQueue)
프론트에서 이루어지는 삭제연산을 디큐(dnQueue)라고 부른다.
💫 큐의 활용 예시
- 프린터의 인쇄 대기열
- 콜센터 고객 대기시간
- 프로세스 관리
- 너비 우선 탐색(BFS, Breadth-First Search) 구현
- 캐시(Cache) 구현