클로저는 내부 함수가 정의될 때 외부 함수의 환경을 기억하고 있는 내부 함수를 말합니다. 외부 함수 안에서 선언된 내부 함수는 그 외부 함수의 지역 변수나 함수에 접근하여 사용할 수 있습니다.
클로저 함수의 기본 형태
// 외부 함수
function closuer() {
// 변수 정의
var count = 0;
// 내부 함수(클로저) 선언
function inner() {
return ++count;
}
// 내부 함수 반환
return inner();
}
// 익명 함수를 이용한 방법
function closure() {
var count = 0;
// 익명 함수(클로저) 반환
return function() {
return ++count;
}
}
클로저 함수 사용 예시
function outter() { // 외부 함수
var data = 1;
function inner() { // 내부 함수
return data;
}
return inner();
}
outter 함수 안에는 지역변수 data와 inner라는 내부 함수가 선언되어 있고 inner 함수를 반환하고 있습니다. inner 함수는 외부에 있는 data 변수를 사용하고 있고 여기까지는 특별한 점이 없어 보입니다.
클로저 함수 호출
var func = outter();
console.log(func);
그런데 outter 함수의 반환 값은 func 변수에는 inner 함수만 저장됩니다. 그 inner 함수를 호출해 보았습니다.
결과
1
outter 함수의 지역변수였던 data의 값 1이 출력되었습니다. 원래는 outter 함수를 호출하지 않았기 때문에 지역변수 data는 사용하지 못하는 것이 일반적이지만 자바스크립트에서는 사용할 수 있다는 것이 매우 특이한 점입니다.
자바스크립트에서는 함수가 선언될 때 자신이 접근할 수 있는 범위를 정하고 기억하고 있는데 이것을 렉시컬 스코프라고 합니다. 그리고 이런 렉시컬 스코프에 의해 외부 함수의 환경을 기억하고 있는 내부 함수가 클로저입니다.
클로저는 클래스와는 꽤나 비슷한 구조를 가지고 있습니다. 그렇기 때문에 클래스 개념이 없는 자바스크립트에서는 클래스 대신하여 쓰이기도 합니다.
클로저 |
클래스 |
클로저를 감싸고 있는 부모 함수 |
생성자 |
클로저가 사용하는 로컬 변수 |
필드(프로퍼티) |
클로저 |
메서드 |
함수 호출 |
인스턴스화 |
클로저에 대입하는 변수 |
인스턴스 |
자바 클래스의 경우
public class People {
// 필드(프로퍼티)
private String name;
// 메서드
public People(name) {
this.name = name;
}
public String getName() {
return name;
}
}
인스턴스화
People people = new People("kim");
// "kim" 반환
people.getName();
자바스크립트의 클로저의 경우
function people(name) {
// 지역 변수
var name = name;
return function() {
return name;
};
}
var getName = people("kim");
// "kim" 반환
getName();
차이점이라고 하면 클래스에서는 메서드를 여러 개 만들 수 있어 다양한 처리가 가능하지만 클로저는 하나의 스코프에 대해 한 개의 처리밖에 할 수 없다는 점입니다. 그렇기 때문에 아예 여러 가지 프로퍼티를 정의한 객체를 반환하여 다양한 처리를 할 수 있게끔 합니다.
클로저는 단독으로 호출돼도 외부 함수의 정보와 연결되어 있기 때문에 값들이 동적으로 바뀌어도 반영된다는 장점이 있습니다.
HTML
<button onclick="print()">버튼</button>
버튼을 누를 때마다 print 함수가 호출됩니다.
JavaScript
var click = (function () {
// 클릭한 횟수를 기억
var count = 0;
return function () {
++count;
return count;
};
})();
// 버튼을 누를 때 마다 누른 횟수 출력
function print() {
console.log(click());
}
print 함수 안에 있는 click 함수는 이름이 없는 클로저를 반환하고 호출하고 있습니다. 클로저는 click 함수의 count변수 값을 계속 기억하고 있으므로 버튼을 누른 횟수를 출력할 수 있습니다.
또한 전역 변수를 대체하여 클로저를 사용할 수 있어서 전역 변수의 남용을 막을 수 있고 변수 값을 은닉하는 용도로도 사용할 수 있습니다.
[JavaScript] 자바스크립트 이벤트의 정의와 이벤트 등록 방법 (0) | 2020.10.24 |
---|---|
[JavaScript] 자바스크립트로 DOM 접근하기 (2) | 2020.10.23 |
[JavaScript] 자바스크립트 콜백(callback)함수란? (0) | 2020.10.12 |
[JavaScript] 자바스크립트 객체 생성 방법 (1) | 2020.10.09 |
[JavaScript] 자바스크립트 JSON의 정의와 메서드 (0) | 2020.10.02 |