[React] 호이스팅과 TDZ는 무엇일까?

이경하·2022년 8월 10일
0
post-thumbnail

✍️ 호이스팅과 TDZ는 무엇일까?

👊 스코프(Scope)

  • 스코프: 변수, 함수, 클래스가 접근할 수 있는 유효 범위
🤜 스코프 구분
- 전역 스코프 (Global scope) : 코드 어디에서든지 참조할 수 있다
- 지역 스코프 (Local scope or Function-level scope)
  : 함수 코드 블록이 만든 스코프로 함수 자신과 하위 함수에서만 참조할 수 있다
    모든 변수는 스코프를 갖는다. 


🤜 변수의 관점에서 스코프를 구분
- 전역 변수 (Global variable) : 전역에서 선언된 변수이며 어디에든 참조할 수 있다
- 지역 변수 (Local variable)
  : 지역(함수) 내에서 선언된 변수이며 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다
    변수는 선언 위치(전역 또는 지역)에 의해 스코프를 가지게 된다
    즉, 전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수이고,
    지역(자바스크립트의 경우 함수 내부)에서 선언된 변수는 지역 스코프를 갖는 지역 변수가 된다

👉 전역 스코프를 갖는 전역 변수는 전역(코드 어디서든지)에서 참조할 수 있다.
   지역(함수 내부)에서 선언된 지역 변수는 그 지역과 그 지역의 하부 지역에서만 참조할 수 있다
🤜 스코프의 주요 규칙

1. 안쪽 스코프에서 바깥쪽 스코프로 접근할 수 있지만 반대는 불가능하다.
바깥쪽 스코프에서 선언한 식별자는 안쪽 스코프에서 사용 가능하다.
반면, 안쪽에서 선언한 식별자는 바깥쪽 스코프에서는 사용할 수 없다.

2. 스코프는 중첩이 가능하다. 스코프는 마치 중첩된 울타리와도 같다.

3. 전역 스코프와 지역 스코프
가장 바깥쪽의 스코프를 전역 스코프(Global Scope)라고 부른다.
전역이 아닌 다른 스코프는 전부 지역 스코프(Local Scope)이다.

4. 지역 변수는 전역 변수보다 우선순위가 더 높다.
전역 스코프에서 선언한 변수는 전역 변수, 지역 스코프에서 선언한 변수는 지역 변수이다.
지역 변수는 전역 변수보다 더 높은 우선순위를 가진다.

👉 화살표 함수는 블록 스코프로 취급한다
🤜 스코프와 var, let, const 키워드

- const 키워드
  유효 범위 : 블록 스코프 / 함수 스코프
  값 재할당 : 불가능
  재선언 : 불가능
  
- let 키워드
  유효 범위 : 블록 스코프 / 함수 스코프
  값 재할당 : 가능
  재선언 : 불가능

- var 키워드
  유효 범위 : 함수 스코프
  값 재할당 : 가능
  재선언 : 가능

👍 변수 은닉화

여러 스코프에서 동일한 식별자를 선언한 경우, 무조건 스코프 체인 상에서 가장 먼저 검색된 식별자에만 접근이 가능
즉, 직접적으로 변경되면 안되는 변수에 대한 접근을 막는것
이렇게 a와 b라는 클로저를 생성하면 함수 내부적으로 접근이 가능


✌️ 스코프 체인

  • 일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결(chain)되고 있는지 보여주는 것

    코드 블럭 안쪽에 있을 수록 바깥을 관측할 순 있지만 코드 블럭 바깥에서 내부의 변수를 참조할 순 없다. 블록 스코프에서 지역 변수 y는 전역 변수 x값을 참조할 수 있고, 반환되는 함수의 지역 변수z는 y의 값을 참조할 수 있다.

    높은 망루(내부 코드 블럭)에 있더라도 완전히 다른 코드 블럭에 속해있는 지역 변수를 참조할 순 없다. 코드 블럭의 실행은 독립적이며 실행이 끝나면 더 이상 참조할 수 없기 때문에 더욱이 다른 위치에서 참조할 수 없다. 전역 스코프에도 참조값이 없다면 null을 반환하게 된다.
스코프 출처 https://hanamon.kr/javascript-%EC%8A%A4%EC%BD%94%ED%94%84%EC%99%80-%EB%B3%80%EC%88%98%EC%84%A0%EC%96%B8%ED%82%A4%EC%9B%8C%EB%93%9C-%EC%B0%A8%EC%9D%B4%EC%A0%90/
스코프 예제 https://velog.io/@oneook/%EC%8A%A4%EC%BD%94%ED%94%84%EC%99%80-%EC%8A%A4%EC%BD%94%ED%94%84-%EC%B2%B4%EC%9D%B8-JavaScript-Basics
스코프체인 출처 https://velog.io/@taek2yo/Javascript-%EA%B0%9C%EB%85%90-%EA%B3%B5%EB%B6%80Scope
변수 은닉화 출처https://velog.io/@hahbr88/%EC%8A%A4%EC%BD%94%ED%94%84-%EC%B2%B4%EC%9D%B8-%EA%B3%BC-%EB%B3%80%EC%88%98-%EC%9D%80%EB%8B%89%ED%99%94

👌 호이스팅(Hoisting)

  • 호이스팅: 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것
🤜 함수 선언식과 함수표현식의 차이
- 주요 차이점 : 호이스팅에서 차이가 발생.

- 함수 선언식 : 함수 전체를 호이스팅
  정의된 범위의 맨 위로 호이스팅되서 함수 선언 전에 함수를 사용할 수 있다는 것
  
- 함수 표현식 :  별도의 변수에 할당하게 되고, 변수는 선언부와 할당부를 나누어 호이스팅 
  선언부만 호이스팅하게 됨
함수 선언식 - 정상으로 해당 값 출력위는 호이스팅이 마치게 되면 다음과 같이 표현할 수 있다. 아래와 같이, 오류나는 부분, 즉 함수 표현식을 코드를 호출하는 부분 위에 작성하면 에러없이 정상적으로 출력. 오류는 나지 않지만, 함수 표현식과 선언식으로 쓰면서 일관성없이 이렇게 작성해야할 필요가 있나 느껴진다

함수 선언식으로 작성한 함수는, 함수 전체가 호이스팅 된다고 하였다. 전역적으로 선언하게 되면, 중복적으로 동명의 함수를 쓰게 된다면, 원치 않는 결과를 초래할 수 있다. 함수 표현식으로 작성하게되면 이를 방지할 수 있다.
호이스팅 출처 https://velog.io/@taek2yo/JavaScript-%EA%B0%9C%EB%85%90-%EA%B3%B5%EB%B6%80%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85

🖖 TDZ(Temporal Dead Zone)

  • TDZ: 일시적 사각지대, 스코프 시작 ~ 초기화 시작 사이의 구간을 의미
    다른 말로 변수가 선언되고 변수의 초기화가 이루어지기 전까지의 구간
🤜 Javascript 의 변수 생성 단계
1. 코드를 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계
2. 초기화 단계(Initialization phase) : 실행 컨텍스트에 등록한 변수를 위한 메모리를 만드는 단계
  메모리가 만들어지면 처음에는 undefined 가 할당
3. 할당 단계(Assignment phase) : 사용자가 undefined 로 할당된 변수에 다른 값을 할당하는 단계
 * var 는 선언과 초기화 단계가 동시에 이루어짐
 * let, const 는 선언, 초기화, 할당 단계가 각각 따로 이루어짐
 * function (함수 선언문) 은 선언, 초기화, 할당 단계가 동시에 이루어짐

👉 선언과 초기화 단계가 따로 이루어 지는 let, const 같은 경우는 TDZ에 영향을 받을 수 밖에 없다
🤜 TDZ에 영향을 받는 것
- let, const, class
- class의 constructor() 내부의 super()
  (클래스의 contructor에서 super함수가 호출되기 전까지 클래스에서 this를 참조하면 에러 발생)
- 함수 매개변수 (매개변수 선언 전에 참조하면 에러 발생)

🤜 TDZ에 영향을 받지않는 것
- var, function (함수 선언식), import (import 구문)
TDZ 출처 https://funveloper.tistory.com/25

🖐️ 실행 컨텍스트(Execution context)

  • scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리
  • 실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경
  • 코드가 실행되는 위치를 설명한다는 뜻의 Execution Context
전역컨텍스트 (Global Execution context)
: 자바스크립트 엔진이 코드를 실행할 때 처음으로 생성되는 실행 컨텍스트

- 아무런 코드가 없어도 두 가지 요소를 가진다.
   1) global object
   2) this (브라우저: Window, Node: global)
   
생성단계
- global object 생성
- this변수 object 생성
- 변수와 함수를 위한 메모리공간 확보
- 변수 선언 부분에 undefined(기본값)로 초기화, 선언식 함수를 메모리 공간에 올림

- 실행단계 (실질적으로 자바스크립트 엔진이 코드를 한 줄씩 읽고 실행하는 단계)
  엔진이 코드를 한 줄씩 실 👉 실제 값을 메모리 공간에 저장
함수실행컨텍스트 (Function Execution context)
: 함수가 호출될 때마다 생성되는 컨텍스트

생성단계
- argument object 생성(🔥글로벌 실행컨텍스트와의 차이점, global object 아님🔥) 
- this 변수 object 생성
- 변수와 함수를 위한 메모리 공간 확보
- 변수 선언 부분에 undefined로 초기화, 선언식 함수를 메모리 공간에 올림

- 함수 실행컨텍스트는 함수가 호출되면 실행 스택에 쌓였다가, 실행을 마치면 콜스택에서 제거됨

- 함수호출 👉 새로운 함수 실행 컨텍스트가 콜스택에 쌓임 👉 생성단계 
  👉 실행단계 👉 콜스택에서 제거

🖐️👍 콜스택(call stack)

  • 코드가 실행되면서 생성되는 Execution Context를 저장하는 자료구조
1. 엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고
   이를 Call Stack에 push한다.
-
2. 엔진이 함수를 호출할 때 마다 함수를 위한 Execution Context를 생성하고
   이를 Call Stack에 push 한다.

3. 자바스크립트 엔진은 Call Stack의 Top에 위치한 함수를 실행하며
   함수가 종료되면 stack에서 제거(pop)하고 제어를 다음 Top에 위치한 함수로 이동한다.

👉 요약 : 프로그램이 함수 호출을 추적할때 사용
출처 https://velog.io/@mincho/%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EC%99%80-%EC%BD%9C-%EC%8A%A4%ED%83%9D
profile
경듀님

0개의 댓글