[JavaScript] 핵심 개념과 주요 문법 | 클로저(Closure)

Eunji Lee·2022년 11월 7일
0

[TIL] JavaScript

목록 보기
8/22
post-thumbnail

Chapter 3. 클로저(Closure)

3-1. 클로저의 의미와 특징

의미

  • 클로저는 '함수'와 '그 함수가 선언된 렉시컬 스코프'와의 조합이다.
    👉🏼 함수와 함수가 태어난 곳의 조합이라고 생각하자
    • 자바스크립트는 함수가 호출되는 환경과 별개로, 기존에 선언되어 있던 환경인 어휘적 환경(렉시컬 스코프)을 기준으로 변수를 조회함
    • 이때 외부 함수의 변수에 접근할 수 있는 내부 함수를 클로저 함수라고 함

특징

함수를 리턴하는 함수

//클로저 함수의 기본 형태
const adder = x => y => x + y;

//위 문장은 다음과 같은 의미임
const adder = function (x) {
	return function (y) {
		return x + y;
	}
}

리턴하는 함수에 의해 스코프(변수의 접근 범위)를 구분할 수 있음

  • 스코프를 활용해서 변수의 접근 범위를 닫을 수 있음

내부함수는 외부 함수에서 선언된 변수에 접근할 수 있음

  • cf) 외부함수는 내부 함수에서 선언된 변수에 접근할 수 없음
const adder = function (x) { //외부함수와 외부함수의 변수인 x
	return function (y) { //내부함수와 내부함수의 변수인 y
		return x + y;
	}
}

데이터를 보존하는 함수

  • 외부함수의 실행이 끝나도, 외부 함수 내 변수가 메모리 상에 저장되기 때문에 외부 함수 내 변수를 사용할 수 있음
  • 특정 데이터를 스코프 안에 가두어둔 채로 계속 사용할 수 있음

예제1.

const adder = function (x) {
	return function (y) {
		return x + y;
	}
}

const add6 = adder(6); // x는 6
add6(6); // 6+6의 결과인 12
add6(8); // 6+8의 결과인 14

예제2.

//HTML 문자열 생성기
const tagMaker = tag => content => `<${tag}>${content}</${tag}>`

const divMaker = tagMaker('div');
divMaker('Jorge'); //'<div>Jorge</div>'
divMaker('Good morning'); //'<div>Good morning</div>'

const anchorMaker = tagMaker('a');
anchorMaker('go'); //'<a>go</a>'
anchorMaker('school'); //'<a>school</a>'

단점

  • 클로저를 남발할 경우 퍼포먼스 저하가 발생할 수도 있음
    • 외부 함수 스코프가 내부 함수에 의해 언제든지 참조될 수 있기 때문
    • 즉, 일반 함수였다면 함수 실행 종료 후 가비지 컬렉션 대상이 되었을 객체가 클로저 패턴에서는 메모리 상에 남아 있게 됨
    • cf) 자바스크립트에서는 객체가 참조 대상이 아닐 때 가비지 컬렉션에 의해 자동으로 메모리 할당이 해제되는 방식으로 메모리 관리가 이루어짐



2-2. 클로저의 활용

대표적인 클로저의 활용 예시

커링(curring)

함수 하나가 n개의 인자를 받는 대신 n개의 함수를 만들어 각각 인자를 받게 하는 방법

클로저 모듈

변수를 외부 함수 스코프 안쪽에 감추어서 변수가 함수 밖에서 노출되는 것을 막는 방법

  • 불필요한 전역 변수 사용을 줄이고, 스코프를 이용해 값을 보다 안전하게 다룰 수 있음
const makeCounter = () => {
	let value = 0;

	return {
		increase: () => {
			value = value + 1;
	},
		decrease: () => {
			value = value - 1;
	},
	getValue: () => value
	}
}

const counter1 = makeCounter();
counter1; // counter1은 객채이며, {increase: ƒ, decrease: ƒ, getvalue: ƒ}가 return
  • makeCounter 함수를 바꾸지 않는다면, 스코프 규칙에 의해 변수 value에 새로운 값을 할당할 수 없음 → 정보의 접근 제한(캡슐화)

모듈화

  • 모듈화: 함수 재사용성을 극대화하여, 함수 하나를 완전히 독립적인 부품의 형태로 분리하는 것
    • 클로저를 통해 데이터와 메서드를 같이 묶어서 다룰 수 있음 → 모듈화에 유리함
const counter2 = makeCounter();
counter2.increase();
counter2.decrease();
counter2.decrease();
counter2.increase();
counter2.increase();
counter2.getValue(); //1

const counter3= makeCounter();
counter3.decrease();
counter3.decrease();
counter3.decrease();
counter3.getValue(); //-3

0개의 댓글