실행 컨텍스트와 콜 스택 , 스코프 체인 이란?

hipAn·2022년 9월 23일
0

끄적끄적 성장일지

목록 보기
14/30
post-custom-banner

실행 컨텍스트와 콜스택이 무엇인가를 찾아보다가

가장 설명이 잘 되어있고 이해하기 쉽게 설명된곳을 찾았다.

내용이 길어 해당내용을 출처와함께 퍼왔다.

반복학습해서 내꺼 만들기

콜스택
콜 스택(Call Stack)은 메모리 상에 함수의 호출과 연관되는 데이터가 저장되는 영역입니다. 함수를 호출하게 되면 스택 영역에 할당이 되고 호출이 되면 끝나고 소멸이 되죠. 자바스크립트는 단일 스레드 프로그래밍 언어이므로 단일 콜 스택이 있습니다. 한번에 하나의 일만 처리할 수 있습니다. 코드 내에 함수는 여러개인데 어떻게 하나의 일만 처리할 수 있을까요?

호출 스택의 예를 먼저 보겠습니다.

const fish = '바다물고기';

function ship() {
console.log('현재 위치는 ship()', fish,'를 잡았다!');
const cat = '해적 고양이';

function flyShip() {
	console.log('현재 위치는  flyShip()', fish, '를 잡았다!');
	console.log('현재 위치는  flyShip()', cat, '를 잡았다!');
	const cat2 = '하늘 고양이';
}
flyShip()

}
ship()
이 코드가 실행이 되면 콜스택에서는 어떤 일이 일어날까요?

아래 그림의 순서대로 함수의 실행 컨텍스트가 쌓이고, 제거되게 됩니다.

  1. 코드가 실행되면 전역 실행 컨텍스트가 생성됩니다.

  2. 그 다음 ship함수가 실행이 되면 ship실행 컨텍스트가 콜스택에 쌓이게 됩니다.

  3. ship함수 내의 flyShip가 실행이 되면 ship실행 컨텍스트의 위로 쌓이게 됩니다.

  4. flyShip함수가 종료되면 flyShip실행 컨텍스트가 제거됩니다.

  5. ship함수가 종료되면 ship실행 컨텍스트가 제거됩니다.

코드가 종료되면 전역 실행 컨텍스트가 제거됩니다.

콜 스택에 실행되는 함수를 위한 스택이 쌓이게 되고, 함수가 종료되면 제거되는 순서를 가지고 있습니다.

이 때 자바스크립트 엔진은 최상단에 위치한(가장 마지막에 생성된 실행 컨텍스트)를 진행하고 있습니다.

함수 내부를 진행하고 코드가 완료되면, 실행 컨텍스트가 제거되고 이전(호출된 후) 코드를 마저 진행하게 됩니다.

실행 컨텍스트
그렇다면 실행 컨텍스트에서는 어떤 일을 할까요?

실행 컨텍스트(Execution Context)는 렉시컬 환경과 변수 환경, This binding으로 이루어져 있습니다.

함수가 호출되면 힙주소에서 함수를 가지고 옵니다. 실행 컨텍스트에서는 현재 실행중이 코드 블록에서 코드들을 한줄씩 읽고, 선언한 변수들을 등록하고 관리하는 작업을 합니다. 그리고 외부 렉시컬 환경을 기록하고 있죠.

LexicalEnvironment: {
envrionmentRecord: {
지역변수, 매개변수 등 보관
},
outerLexicalEnvrionment: 현재 코드가 실행중인 렉시컬 스코프에 대한 참조
}

실행 컨텍스트에서는 코드를 실행하는 쓰레드와 로컬 메모리 영역(지역변수, 매개변수 등이 보관됨), 렉시컬 스코프를 참조할 수 있도록 기록되어지는 공간이 있습니다.

콜스택영역에서 함수가 호출되면 실행 컨텍스트가 쌓인다.라고 했었죠, 이전 코드를 예로 다시 실행 컨텍스트를 그려보겠습니다.

여기에서 중요한 외부 렉시컬 환경을 기록 <- 렉시컬 스코프 이해의 시작이 됩니다.

스코프
사랑하는 MDN의 설명을 먼저 보시겠습니다.

저는 여기 번역된 현재 실행되는 컨텍스트를 뜻한다는 의미에서 헷깔렸습니다. 다른 블로그들을 찾아봐도 스택, 실행 컨텍스트를 혼용해서 사용하다보니 더욱 헷깔렸죠.

스코프는 값과 표현식이 표현되거나 참조 될 수 있음을 의미,

"해당 스코프 내에 있지 않다면 사용할 수 없다." , "하위 스코프는 상위 스코프에 접근할 수 있지만 반대는 불가하다."

이미지와 함께 다시 설명해보겠습니다.

콜 스택에 쌓인 실행 컨텍스트는 최상단이 현재 실행되고 있는 컨텍스트입니다.

현재 3개의 실행 컨텍스트가 쌓여있죠? 최상단에 쌓인 flyShip()의 코드가 실행되고 있습니다.

이때 flyShip()에서 fish를 찾는다면 어떻게 될까요?

  1. 먼저 현재 실행하고 있는 컨텍스트의 메모리에서 변수 fish를 찾습니다.

  2. 찾지 못하면 렉시컬 스코프를 참조해(그림으로 닻으로 표현) ship 실행 컨텍스트로 이동해 찾습니다.

  3. ship 실행 컨텍스트에서 찾지 못한다면 렉시컬 스코프를 참조해 전역 실행 컨텍스트로 이동해 찾습니다.

  4. 변수를 발견하면 값을 가지고 코드를 마저 실행합니다.

이 때 스코프는 현재 실행중이 실행컨텐스트를 기준으로 행동합니다.

만약 ship()에서 cat2 하늘고양이를 찾는다면 어떻게 될까요?

닻을 타고 올라갈 수 없습니다. ship컨텍스트에는 상단으로 가는 지도, 길이 없습니다. 하위로 찾아갈 수 있습니다.

예 해적고양이는 하늘고양이 영역에 갈 수 없습니다(입체적으로 이해해보기..)

이 스코프는 함수가 호출된 실행 컨텍스트로 찾아가는 닻(링크)라고 생각하시면 좋습니다.

스코프 체이닝
그리고 이렇게 닻(렉시컬 스코프)들이 계층적으로 연결되어있걸 스코프 체이닝이라고 합니다.

post-custom-banner

0개의 댓글