렉시컬 스코프

mseo39·약 17시간 전

TIL

목록 보기
20/20

렉시컬 스코프란

  • 함수를 어디서 호출하는지가 아니라 어디에 선언했는지에 따라 변수의 유효 범위가 결정되는 규칙
  • 소스 코드가 컴파일되는 시점에 물리적인 위치에 의해 스코프가 고정되기 때문에 '정적 스코프'라고도 불린다

예를 들어 아래 코드를 실행한다면 어떤 결과가 나오게 될까?

let x = '전역 변수'

function foo() {
	let x = 'foo의 지역변수';
	bar();
}

function bar() {
	console.log(x);
}

foo();

출력--
전역 변수

bar()가 foo() 내부에서 호출되었기 때문에 foo 안의 x인 'foo의 지역변수'를 출력할 것이라고 생각할 수 있지만 자바스크립트는 렉시컬 스코프를 따르기 때문에 '전역 변수'가 출력된다

대체 내부에서는 어떤 일이 벌어지길래 이런 결과가 나오는 걸까?

동작 과정

코드를 실행할 때 실행 흐름을 제어하는 Call Stack과 실제 데이터와 변수를 저장하는 Heap영역을 나누어 사용한다

① 전역 초기화

Call Stack : 앱이 실행되면서 가장 먼저 전역 실행 컨텍스트가 생성되어 Stack에 삽입
Heap : 전역 렉시컬 환경 객체 생성

  • 환경 레코드: 변수 x와 함수 foobar
  • 외부 렉시컬 환경 참조: 최상위이므로 null

② foo() 함수 실행

Call Stack  : foo()가 호출되면서 전역 컨텍스트 위에 foo 실행 컨텍스트를 쌓음
Heap : foo 렉시컬 환경 객체 생성

  • 환경 레코드: foo 내부의 지역 변수인 let x
  • 외부 렉시컬 환경 참조: foo 함수는 전역 공간에 선언되었기 때문에 전역 렉시컬 환경의 주소를 가리킴

③ bar() 함수 실행

Call Stack : foo 내부에서 bar()가 호출되면서 Call Stack 최상단에 bar 실행 컨텍스트가 쌓임
Heap : bar 렉시컬 환경 객체 생성

  • 환경 레코드: 내부가 비어있으므로 기록된 변수 X
  • 외부 렉시컬 환경 참조:
    • 전역 렉시컬 환경의 주소를 참조
    • bar 함수가 호출된 곳은 foo 내부이지만 실제 코드가 선언된 곳은 전역이기 때문

Scope Chain

변수 x를 찾기 위한 탐색 과정

  1. 현재 활성화된 bar 환경 레코드 탐색 → x가 없음
  2. 외부 참조 추적 (스코프 체인 이동): bar에 x가 없으므로 외부 렉시컬 환경 참조를 타고 전역 렉시컬 환경으로 넘어감
  3. 상위 레코드 탐색: 전역 렉시컬 환경의 환경 레코드 확인 → let x = '전역 변수'
  4. 값 반환: 최종적으로 '전역 변수'라는 결과물이 화면에 출력

💡 스코프 체인(Scope Chain)이란? 
이렇게 현재 렉시컬 환경의 레코드에서 변수를 찾지 못했을 때 외부 렉시컬 환경 참조를 따라 상위 스코프로 꼬리에 꼬리를 물고 이동하며 변수를 찾아 나가는 단방향 링크드 리스트 구조를 '스코프 체인'이라고 한다

profile
하루하루 성실하게

0개의 댓글