JavaScript 핵심 개념 정리 - Closure

JavaScript 핵심 개념 정리 - Closure

Closure란 무엇일까? JavaScript를 공부하는 사람이라면 한 번쯤을 들어봤을 것이다!

Closure

A closure is the combination of a function and the lexical environment within which that function was declared.

MDN에서는 Closure를 위와 같이 정의하고 있다.

의역을 해보면 Closure는 함수와 그 함수가 내부에 선언된 lexical environment의 조합이라고 한다. 무슨 말인지 전혀 모르겠다..😐😐

lexical environment

  • 선언 당시의 환경에 대한 정보를 담는 객체

lexical environment가 뭔지 알 수 있다면 좀 더 이해가 편해질 거 같다!

사전에서 치즈를 검색해보면 치즈는 어떻게 만들어졌고, 성분은 무엇인가? 를 알 수 있다.

바로 이것을 lexical environment라고 이해할 수 있다.

그 결과, Closure는 함수와 그 함수가 선언될 당시 환경정보의 조합으로 발생하는 어떠한 현상 / 상태라고 생각할 수 있다!

함수 Scope가 유효 범위인 곳에서 어떠한 코드를 작성하든, Scope 및 lexical environment는 변하지 않는다

-> 최초 선언 시의 정보를 유지!

그리고 함수 Scope에서 외부에 정보를 전달할 수 있는 수단은 무엇일까? 바로 Return이다.

이 두 가지를 활용하는 Closure는 크게 3가지 장점이 있다.

  • 접근 권한 제어
  • 지역변수 보호
  • 데이터 보존 및 활용
function a() {
	var x = 1;
	function b() {
		console.log(x);
	}
	b();
}
a();
console.log(x);

위 코드에서 함수 a에서 선언된 x를 함수 b에서는 접근할 수 있다.

하지만, 함수 a의 외부에서는 접근할 수 없다.

따라서 외부에서의 console.log(x)는 에러를 발생시킨다.

그렇다면 함수 a 내부에 선언된 x를 외부에서 사용할 수 있는 방법은 없을까?

function a() {
	var x = 1;
	return function b() {
		console.log(x);
	}
}
var c = a();
c();

위 코드에서 바로 Closure의 장점을 확인할 수 있다.

함수 a 내부에서 함수 b를 return함으로써 x를 외부에서 사용할 수 있게 되었지만,

x의 값을 바꿀 수 없다!

바꿀 수 있는 권한을 주고 싶다면 set 함수 등을 정의하여 return하면 된다.

function setCounter() {
	var count = 0;
	return function() {
		return ++count;
	}
}
var count = setCounter();
count();

Closure로 Private Member 만들기!

친숙한 Java, C++ 등의 언어에서는 Method, Property 등을 Private으로 선언할 수 있는 기능이 있다.

JavaScript는 기본적으로 이러한 기능이 제공되고 있지는 않지만, Closure를 활용해 이를 대략 흉내 낼 수 있다.

Private Member를 만드는 이유는 크게 2가지가 있다.

  • 접근 제어
  • 전역 변수 최소화
var car = {
	fuel: 10,
	power: 2,
	total: 0,
	run: function(km) {
		var wasteFuel = km / this.power;

		if(this.fuel < wasteFuel) {
			console.log('이동 불가');
			return;
		}
		this.fuel -= wasteFuel;
		this.total += km;
	}
}

위 코드로 어떤 게임을 만든다고 가정해보자!

특정한 사용자가 외부에서 car.power = 10; car.fuel = 1000;등의 코드를 입력할 수 있기 때문에 위와 같은 방식은 적절하지 않다.

그럼 Private 기능을 활용하여 코드를 다시 만들어보자!

var createCar = function (f, p) {
	var fuel = f;
	var power = p;
	var total = 0;

	return {
		run: function (km) {
			var wasteFuel = km / power;

			if (fuel < wasteFuel) {
				console.log('이동 불가');
				return;
			}
			fuel -= wasteFuel;
			total += km;
		}
	}
};
var car = createCar(10, 2);

위 코드에서는 car.power = 10; car.fuel = 1000;등의 코드를 외부에서 입력할 수 없다! 사용자는 run이라는 Method만 사용할 수 있다.

Closure를 활용해 Private를 활용하는 순서는 아래와 같다 1. 함수에서 지역변수 및 내부함수 등을 생성한다.

2. 외부에 노출시키고자 하는 멤버들로 구성된 객체를 return한다.

Closure 정리

return function : 최초 선언시의 정보를 유지 !

-> return에 포함된 객체 Public, 포함되지 않은 객체 Private

-> Closure의 장점 3가지(접근 권한 제어, 지역변수 보호, 데이터 보존 및 활용) 활용 가능!

Closure는 객체지향, Scala와 같은 함수형 언어의 Curring 등에서도 활용되기 때문에 반드시 알아두자!

마무리

원래 중요하게 생각하고 공부한 개념이었지만, 글을 쓰며 한 번 더 배운 느낌이다!

다음 포스팅에서는 prototype, Class 등에 대해 설명할 예정이다! 😎😎

본 포스팅은 인프런 강의 Javascript 핵심 개념 알아보기 - JS Flow를 공부하며 정리한 포스팅입니다!