[TIL 17] 컨텍스트와 스코프 체인

_dodo_hee·2021년 3월 4일
0

JAVASCRIPT

목록 보기
9/17
post-thumbnail

클로저를 배울려면 컨텍스트에 대해 먼저 공부해야하고, 컨텍스트를 배울려면 this도 정리해야하고, this는 이해가 안되고 이해가 안되는데 할 건 많고 허허 😇

실행 컨텍스트 Execution Context

자바스크립트 엔진은 실행 가능한 코드를 만나면 평가해서 실행 컨텍스트로 만든다.

실행컨텍스트는 스택이라는 구조로 관리된다.

# 스택?

자료구조 데이터를 아래서부터 쌓아 올려서 마지막으로 추가한 데이터를 먼저 꺼내는
후입선출 방식으로 관리된다.

컨텍스트는 함수가 호출될때 push되고 종료될때 pop 된다.

push : 데이터를 쌓는 행위
pop : 데이터를 빼내는 행위

(사진으로 보면 이해하기 쉬워서 사진 첨부 링크)
호출스택예시사진

# 실행 가능한 코드?

실행 가능한 코드를 영어로 Executable Code (엑스~큣어블 코드😊)

  1. 전역 코드
  2. 함수 코드
  3. eval 코드

왜 전역,함수,eval 로 분리할까? 🧐

실행 컨텍스트를 초기화하는 환경과 과정이 다르기 때문이다.
그런데 eval 코드만 특이하게 렉시컬 환경이 아니라 별도의 동적 환경에서 실행 된다.

프로그램을 평가 한 후에 동작은? 🧐

실행 가능한 코드를 만나면 평가한 다음에 실행 컨텍스트를 만든다 했으니까,
프로그램은 실행 컨텍스트 안에서 실행된다.

# 실행 컨텍스트의 구성

실행 컨텍스트는 실행에 필요한 모든 정보를 컴포넌트 여러 개가 나누어 관리하도록 만들어져 있다.

  • 렉시컬 환경 컴포넌트
  • 변수 환경 컴포넌트
  • 디스 바인딩 컴포넌트

(렉시컬 환경 컴포넌트와 변수 환경은 거의 동일하게 사용되서 렉시컬 환경 타입의 컴포넌트로 불림.)

# 렉시컬 환경 컴포넌트

렉시컬 환경 컴포넌트는 자바스크립트 엔진이 코드를 실행하기 위해 자원을 모아 둔 곳.
함수 또는 블록의 유효 범위 안에 있는 식별자와 결과값이 저장되는 곳.

  • 환경 레코드
  • 외부 렉시컬 환경 참조

환경 레코드

유효 범위 안의 식별자와 결과값을 묶어서 환경 레코드에 기록

외부 렉시컬 환경 참조

함수를 둘러싸고 잇는 코드가 속한 렉시컬 환경 컴포넌트의 참조가 저장.
중첩된 함수 안에서 바깥 코드의 변수를 읽거나 써야 할 때,
자바스크립트 엔진이 렉시컬 환경을 거슬러 올라가서 변수를 검색.


스코프 체인 Scope chain

(스코프 체인은 제로초님 강의로 공부를 했다.)

전역 변수의 유효 범위는 코드 전체.
함수 안에 있는 지역 변수 유효범위는 함수 안에 전체 코드.
이때, 중첩함수,외부함수,전역코드에 같은 이름 변수를 가지면 충돌.

🔍스코프 체인을 볼때 팁!🔍
1. 먼저 코드를 접어라
  - 같은 범위에 있는지 먼저 파악하기.
2. 스코프 체인 따라서 변수가 어떻게 변하는지 추적해라.

코드가 적힌 순간 스코프가 정해지는 것을 렉시컬 스코핑라고 부른다.

# 헷갈릴 수 있는 예제 살펴보기

밑에 나오는 코드는 비슷하지만 결과는 다른 모습을 보여준다.
헷갈릴 수 있으니까 꼭 다시 한번 보고 지나가자.

코드 예제 (변수를 재할당) ✍️

var name = "dohee"; //dodo로 변경

function log() {
 	console.log(name); //dodo
}

function result(){
	name = "dodo";
  	log();
}

result(); //dodo

🔍 코드를 읽을땐,

result() -> result 함수의 변수는 dodo -> let name = "dodo" 로 변경 ->log()함수의 console.log(name)dodo -> dodo 가 출력.

💁‍♀️ 왜 값이 이렇게 나왔지?

function result에 변수를 선언한게 아니라 재할당을 해줘서 var name = "dodo" 로 바뀐 상태가 된 것이다.

코드 예제 (변수를 선언) ✍️

var name = "dohee";

function log() {
 	console.log(name); //dohee
}

function result(){
	var name = "dodo";
  	log();
}

result(); //dohee

🔍 코드를 읽을땐,

result() -> result 함수의 변수는 dodo -> log()함수의 console.log(name) 실행
-> name이 선언된게 함수안에 있는지 확인 -> 없으면 전체에서 name에 대한 변수를 찾는다.
-> dohee 가 출력.

💁‍♀️ 왜 값이 이렇게 나왔지?

여기서, result의 변수가 dodo로 선언되어도 function log()와 다른 범위기 때문에
log()를 출력했을때 function log()안에 name으로 지정된 변수가 없어서
바깥의 변수를 가져오는 것이다.


가비지 컬렉션

객체를 생성하면 메모리 공간이 자동으로 확보가 되는데
이때, 사용하지 않는 객체를 가비지 컬렉터가 걸러줘서 메모리 공간을 넓혀준다.

🖐 짚고 넘어가면 좋을 것🖐
주요 웹 브라우저에서 마크 앤 스윕이란 알고리즘을 사용. 가비지컬렉션이랑 비슷한 방식.


this 공부하기 너무 무서운걸...

profile
무럭무럭 자라나는 도도 개발성장일기

0개의 댓글