나만보는개발공부블로그

Closure 본문

Javascript&Typescript

Closure

alexrider94 2021. 2. 19. 22:20

클로저란?

 주변 state들이 lexical environment에 대한 참조와 함께 묶이거나 또는 포함되어 있는 함수의 조합이다. 다른말로 클로저는 내부함수에서 외부 함수의 scope에 접근할 수 있다.

자바스크립트에서는 함수가 생성될때 마다 클로저가 생성된다.

 

 클로저를 사용하기 위해서는 함수내에 다른함수를 정의하고 그 함수를 반환하거나 다른함수로 전달하면 된다. 내부 함수에서 외부함수가 반환되도 그 외부함수의 변수를 사용할 수 있다.

 

클로저의 특징

무엇보다도 클로저는 일반적으로 객체의 데이터 프라이버시(보호)를 제공하는 데 사용된다.

 

- data privacy

데이터 프라이버시는 인터페이스를 구현하는데에 필수 속성이다. 이러한 개념들은 더 견고한(?) 소프트웨어를 구축하는데 있어서 중요하다. 왜냐하면 구현의 세부 사항이 인터페이스 계약보다 깨지는 방식으로 변경 될 가능성이 더 높기 때문이다.

 

JavaScript에서 클로저는 데이터 프라이버시를 활성화하는 데 사용되는 기본 메커니즘이다. 데이터 프라이버시를 위해 클로저를 사용하는 경우 에워싸여진 변수는 포함된 (외부) 함수 내의 범위에만 있다. object의 권한이 있는 메서드를 통하지 않는 한 외부 범위에서 데이터를 가져올 수 없다. JavaScript에서는 클로저 범위 내에 정의 된 메서드는 권한이 있다.

 

예시

var func = [];

for (var i = 0; i < 3; ++i) {
	func.push(function(){console.log(i)});
}

for (var j = 0; j < 3; ++j) {
	func[j]();
}

위의 코드 실행 결과로 0,1,2를 기대할 수 있지만 결과는 3이 세번 출력된다. 그 이유는 for 루프의 var i가 전역 변수이기 때문이다.

 

아래와 같은 코드로 수정하면 가능하다. 

var func = [];

for (var i = 0; i < 3; ++i) {
	(function (index) {
    	func.push(function () { console.log(index); });
    }(i));
}

for (var j = 0; j < 3; ++j) {
	func[j]();
}

자바스크립트 함수 레벨 스코프로 인하여 for 루프의 초기화 식에 사용된 변수가 전역 스코프를 갖게 되어 발생하는 문제를 회피하기 위해 클로저를 활용한 방법이다.

 

ES6의 let 키워드를 for 루프의 초기화 식에 사용하면 클로저를 사용하지 않아도 위 코드와 동일한 동작을 한다.

var func = [];

for (let i = 0; i < 3; ++i) {
    func.push(function () { console.log(i); });
}

for (var j = 0; j < 3; ++j) {
	func[j]();
}

 

for 루프의 let i 는 for 루프의 코드 블록에서만 유효한 지역 변수이다. 또한 i는 자유 변수로서 for 루프의 생명주기가 종료되어도 변수 if르 참조하는 함수가 존재하는 한 계속 유지된다.

'Javascript&Typescript' 카테고리의 다른 글

classical & prototypal inheritance in javascript  (0) 2021.02.22
Declarative and Imperative programming  (0) 2021.02.21
Event loop - 2  (0) 2021.02.17
Event loop - 1  (0) 2021.02.16
Functional Programming  (0) 2021.02.11