JavaScript Deep Dive 24

harbour·2022년 7월 22일
0

숨 참고 Deep Dive ~

목록 보기
8/8
post-thumbnail

Ch24. Closuer

⚠️ 클로저는 자바스크립트 고유의 개념이 아니다!
함수를 일급 객체 취급하는 함수형 프로그래밍 언어(ex 하스켈, 리스프, 얼랭, 스칼라 등)에서 사용되는 중요한 특성이다.

일급 객체 : 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체

그래서 클로저란?

클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.

무슨 말인지 모르겠다.
함수가 선언된 렉시컬 환경이 뭔지 살펴보자

const x = 1

function outerFunc() {
const x = 10;
	function innerFunc() {
    console.log(x); // 10
    }
    innerFunc();
  }
 outerFunc();

여기서 중첩 함수 innerFunc()의 상위 스코프는 외부 함수 outerFunc()의 스코프이기 때문에 innerFunc에서도 outerFunc의 x 변수에 접근할 수 있다.

const x = 1;

function outerFunc(){
  const x = 10;
  innerFunc();
}
function innerFunc(){
  console.log(x); //1
}
outerFunc();

innerFunc가 outerFunc 내부에서 호출하더라도 outerFunc의 x 변수에는 접근할 수 없다.
-> 자바스크립트는 렉시컬 스코프를 따르는 프로그래밍 언어이기 때문

렉시컬 스코프?

자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정하는데 이를 렉시컬 스코프(정적 스코프)라고 한다.

const x = 1;

function foo() {
const x = 10;
bar();
}

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

foo();
bar();

foo() bar() 모두 전역에서 정의된 전역 함수다. 어디서 정의했느냐 에 따라 상위 스코프가 결정되기 때문에 전역 함수 -> 상위 스코프도 전역

따라서 "함수의 상위 스코프를 결정한다" 라는 것은
"렉시컬 환경의 외부 렉시컬 환경에 대한 참조를 저장할 참조값을 결정한다!" 라는 것과 같다.

함수 객체의 내부 슬롯

함수가 정의된 위치와 호출되는 위치는 다를 수 있다.
렉시컬 스코프가 가능하려면? 함수는 호출되는 위치와는 상관 없이 정의된 위치의 상위 스코프를 기억해야 한다.
-> 함수는 자신의 내부 슬롯 [[Environment]]에 자신이 정의된 환경, 상위 스코프의 참조를 저장한다.

const x = 1;
//1번
function outer() {
 const x = 10;
 const inner = function () {
  console.log(x) //2번
 };
 return inner;
}

const innerFunc = outer(); //3번
innerFunc(); //4번 10

outer 함수를 호출하면 중첩 함수 inner를 반환하고 생명주기(라이프사이클)을 마감한다. -> 호출 후 실행컨텍스트 스택에서 제거된다.
이때 outer 함수의 지역변수 x와 변수 값 10을 저장하고 있던 outer 함수의 실행 컨텍스크가 제거되었으니 outer 함수 지역 변수 x 또한 생명주기를 마감한다. 따라서 outer 함수의 지역변수 x는 더는 유효하지 않게 되니 x 변수에 접근할 수 없을 것 같지만..? 4번 innerFunc함수를 실행하면 outer험수의 지역변수 x값인 10이 호출된다.

외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이런 중첩 함수를 클로저 라고 부른다

profile
Onion on Sale

0개의 댓글