클로져가 이해가 안 돼서 찾아본 보석같은 영상인
유튜브 우아한 Tech - 엘라의 Scope & Closure 영상을 정리한 글입니다
(출처 : https://youtu.be/PVYjfrgZhtU)
//출처 영상에서 예시로 나온 코드입니다
var x = "나는 전역 x야";
function outer() {
var y = "나는 outer 함수의 지역 y야";
console.log(x); //① 나는 전역 x야
console.log(y); //② 나는 outer함수의 지역 y야
function inner() {
var x = "나는 inner 함수의 지역 x야";
console.log(x); //③ 나는 inner 함수의 지역 x야
console.log(y); //④ 나는 outer함수의 지역 y야
}
inner();
}
outer();
console.log(x); //⑤ 나는 전역 x야
console.log(y); //⑥ 레퍼런스 에러
변수를 참조할 때 자바스크립트엔진은 스코프체인을 통해 변수를 참조한다
만약 어떤 함수가 어떤 변수를 참조하려고 할 때 함수가 있는 스코프 안에 그 변수가 없다면 상위 스코프로 올라가서 참조할 수 있다(원하는 변수를 찾을 때까지 상위 스코프로 하나씩 올라감(무조건 위로만 올라감(단방향성)) 지역 스코프까지 올라갔는데도 원하는 값이 없다면 레퍼런스 에러가 발생하게 됨
그렇기 때문에 하위 스코프에서 상위 스코프를 참조하는 것은 되지만 그 반대는 안 됨
스코프 레벨을 기준으로 블록 레벨 스코프와 함수레벨 스코프로 나눌 수 있다
블록레벨 스코프(대부분의 프로그래밍 언어) : if문, for문, 함수 등의 코드블록이 지역변수를 만드는 데 이런 특성을 블록레벨 스코프라고 한다
함수레벨 스코프(자바스크립트): 자바스크립트는 var로 선언된 변수는 오로지 함수 코드블록만을 지역스코프로 인정함
상위 스코프가 결정되는 시점을 기준으로 정적 스코프와 동적 스코프(렉시컬 스코프)로 나뉨
동적 스코프 : 함수가 호출되는 시점에 상위 스코프가 결정되는 것
정적 스코프(렉시컬 스코프) : 함수가 정의되는 시점(만들어지는 순간)에 상위 스코프가 결정되는 것
자바스크립트는 렉시컬 스코프를 따르기 때문에 함수는 정의되자마자 바로 상위 스코프가 결정됨 이후 해당 함수에 의해 함수 객체가 생성이 되면 해당 함수 객체는 본인의 상위 스코프를 항상 알 수 있게 됨 그 이유는 함수는 정의되면서부터 상위 스코프의 참조를 내부 슬롯에 저장하기 때문
어떠한 중첩함수가 상위 스코프의 식별자를 참조하고 있고, 본인의 외부 함수보다 더 오래유지가 된다면 이 중첩함수는 클로져이다
이러한 클로저는 현재 본인의 상위 스코프에서 현재 참조하는 식별자만을 기억한다
클로져에 의해 참조된 변수를 자유변수라고 한다
이러한 클로저는 하나의 문(statement)가 실수로 변경되지 않도록 statement를 안전하게 은닉하고 또는 특정 함수에게만 state변경을 허용하기 위해 사용함