클로저 D1

nearworld·2023년 1월 8일
0

javascript

목록 보기
5/7

클로저하면 바로 튀어나오는 단어가 렉시컬 환경.
렉시컬 환경은 2가지로 구성되어 있다.
1. 환경 레코드 (Environment Record): 모든 지역 변수를 프로퍼티로 갖는 객체
2. 외부 렉시컬 환경에 대한 참조: 함수 외부 코드에 접근

let a = 0;

function print() {
	return a;
}

위 코드에서 렉시컬 환경 2개를 생각해 볼 수 있다.

  1. 최상위 렉시컬 환경인 '전역 렉시컬 환경'
  2. print 함수 내부의 렉시컬 환경

이때, 2번인 함수 내부의 렉시컬 환경은 외부 렉시컬 환경인 1번의 전역 렉시컬 환경을 참조할 수 있다.

렉시컬 환경이 외부 렉시컬 환경을 참조하는 동작은 null을 참조할때까지 반복한다.

위 코드에서 외부 렉시컬 환경들을 참조해나가는 체인의 시작점인 print 함수의 렉시컬 환경은 print 함수가 만들어 질 때 함수에 등록된 [[Environment]] 라는 숨김 프로퍼티에 참조가 저장된다.

단계별로 보자면,

let a = 1;

function print() {
  return console.log(a);
}

print();

런타임 이전의 상황
1. print 함수가 만들어졌고 이 함수는 [[Environment]]라는 숨김 프로퍼티를 갖게되고 이 숨김 프로퍼티 내부에는 print 함수의 렉시컬 환경에 대한 참조가 저장된다.
2. print 함수의 렉시컬 환경에는 아무것도 저장되어 있지 않다. 이유는 변수가 선언된게 없기 때문이다.
3. 변수 a가 전역 렉시컬 환경에 저장되고 값은 uninitialized.

런타임 상황
1. 변수 a 의 값이 1로 전역 렉시컬 환경에 저장된다.
2. print 함수가 호출되고 함수의 숨김 프로퍼티인 [[Environment]]에 저장된 함수 내부의 렉시컬 환경에 대한 참조를 통해 함수 내부에 저장된 변수가 있는지 확인한다. 저장된 변수가 없으므로 외부 렉시컬 환경을 참조한다.
3. 외부 렉시컬 환경에 변수 a가 저장되어 있으므로 해당 변수 a의 값을 사용한다

!
함수와 외부 렉시컬 환경의 조합 = 클로저
클로저는 비순수함수일까?
결론: 상황에 따라 다르다.

let a = 10;
function add(x) {
  a += 10;
  return a + x;
}

add(10); // 외부 렉시컬 환경에 있는 a의 값이 변경되었으므로 이때 add 함수는 비순수 함수이며 클로저.
const a = 10;
function add(x) {
  return a + x;
}

add(10); // a의 값이 변경 불가능하므로 add 함수는 외부 상태 변경에 어떤 영향도 미칠 수 없고 항상 같은 인자에 같은 결과값이 대응되므로 순수 함수다 그리고 외부 렉시컬 환경을 참조하므로 클로저.
profile
깃허브: https://github.com/nearworld

0개의 댓글