클로저
<클로저의 의미 및 원리 이해>
함수를 선언할 때 만들어진 유효범위가 사라진 후에도 호출할 수 있는 함수
이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수
자신이 생성될 때의 스코프에서 알 수 있었던 변수들 중 언젠가 자신이 실행될 때 사용할 변수들만을 기억하여 유지시키는 함수
~'선언될 당시의 lexical environment'는 2장에서 소개한 실행 컨텍스트의 구성 요소 중 하나인 outerEniromentReference에 해당합니다. LexicalEnvironment의 environmentRecord와 outerEnvironmentReference에 의해 변수의 유효범위인 스코프가 결정되고 스코프 체인이 가능해진다고 했습니다. 어떤 컨텍스트 a에서 선언한 내부함수 b의 실행 컨텍스트가 활성화된 시점에는 b의 outerEnvironmentReference가 참조하는 대상인 A의 LexicalEnvironment에도 접근이 가능하겠죠. A에서는 B에서 선언한 변수에 접근할 수 없지만 B에서는 A에서 선언한 변수에 접근가능합니다 ~
예제 5-3 외부 함수의 변수를 참조하는 내부 함수
var outer = function() {
var a = 1;
var inner = function() {
return ++a;
};
return inner;
};
var outer2 = outer();
console.log(outer2()); //2
console.log(outer2()); //3
inner 함수 자체를 반환한 경우겠다
inner 함수의 실행 시점에는 outer 함수는 이미 시행이 종료된 상태인데 어떻게 outer함수의 LexicalEnvironment에 접근할 수 있는 것인가?
->가비지 컬렉터의 특징
->참조하는 변수가 하나라도 있으면 GC의 수집 대상이 되지 않는다
가비지 컬렉터의 수집 대상에서 제외되는 경우는 위와 같이 지역변수를 참조하는 내부함수가 외부로 전달된 경우가 유일하다
"어떤 함수에서 선언한 변수를 참조하는 내부함수에서만 바생하는 현상" = "외부 함수의 LexicalEnvironment가 가비지 컬렉팅되지 않는 현상"
즉 크로저란 어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 외부로 전달하 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상
return을 쓰지 않아도 지역변수를 참조하는 내부 함수를 외부에 전달하기만 하면 클로저라고 할 수 있다
<클로저와 메모리 관리>
'메모리 누수' 의도와는 달리 참조 카운트가 0이 되지 않아 GC의 수거 대상이 되지 않는 경우
클로저는 의도적으로 함수의 지역변수를 메모리를 소모하도록 함으로써 발생한다, 필요성이 사라지면 메모리를 소모하지 않게 null이나 undefined를 할당하면 된다
<클로저 활용 사례>
예제 5-
var fruits = ['apple', 'banana','peach'];
var $ul = document.createElement('ul');
fruits.forEach(function (fruit) {
var $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click',function() {
alert('your choice is ' + fruit);
});
$ul.appendChild($li);
})
document.body.appendChild($ul);
#✅ var $ul = ...에서 $는 무슨 의미인가요?
👉 사실 아무 의미도 없어요!
$는 유효한 변수 이름 문자입니다.
개발자들이 변수 이름 앞에 $를 붙이는 건 **"DOM 요소임을 표현"**하려는 일종의 코딩 습관이에요
예제 5-9
var fruits = ['apple', 'banana','peach'];
var $ul = document.createElement('ul');
var alearFruitBuilder = function (fruit) {
return function() {
alert('your choice is ' + fruit);
};
};
fruits.forEach(function (fruit){
var $li = document.createElement("li");
$li.innerText = fruit;
$li.addEventListener('click',alearFruitBuilder);
$ul.appendChild($li);
});
접근 권한 제어
정보 은닉
public private protected가 있는데
자바스크립트가 권한을 부여하도록 설계되어있지는 않다. 하지만 클로저를 이용하면 public과 private를 구분할 수 있다
return을 활용해서 선택적으로 일부의 변수에 대한 접근 권한을 부여할 수 있다
외부에 제공하고자하는 정보들을 모아 return하고 내부는 하지 않는 것으로 접근 권한 제어가 가능한 것이다
1. 함수에서 지역 변수 및 내부 함수 등을 생성한다
2. 외부에 접근권한을 주고자 하는 대상으로 구성된 참조형 데이터를 return합니다
-> return 한 변수들은 공개 멤버가 되고 그렇지 않은 변수들을 비공개 멤버가 된다
부분 적용 함수
:n개의 인자를 받는 함수에 미리 m개의 인자만 넘겨 기억시켰다가, n-m 개를 넘기면 비로소 원래 함수의 실행결과를 얻을 수 있게끔하는 함수이다
커링 함수
여러 개의 인자를 받는 함수를 하나의 인자만 받는 함수로 받아서 순차적으로 호출될 수 있게 체인 허형태로 구성한 것
한 번에 하나의 인자만 전달함
마지막 인자가 전달하기 위해 원본 함수가 실행되지 않음
<정리>
실행 컨텍스트가 종료된 후에도 해당 변수가 사라지지 않는 현상
return으로 함수를 전달하거나 콜백으로 전달하는 방법도 있음
콜백은 메모리를 차지하지 않도록 관리해준다
'교재 > 코어 자바스크립트' 카테고리의 다른 글
코어 자바스크립트 | 챕터 7: 클래스 (0) | 2025.04.26 |
---|---|
코어 자바스크립트 | 챕터 6: 프로토타입 (0) | 2025.04.26 |
코어 자바스크립트 | 챕터 4: 콜백 함수 (0) | 2025.04.24 |
코어 자바스크립트 | 챕터 3: this (0) | 2025.04.24 |
코어 자바스크립트 | 챕터 2: 실행 컨텍스트 (1) | 2025.04.22 |