클로저란

puka·2022년 9월 13일

클로저란

클로저란 독립적인(자유)변수를 가리키는 함수이다.  
외부함수가 소멸된 이후에도 내부함수가 소멸된 외부함수의 변수에 접근 할 수 있다. 
그 이유는 메모리에서는 여전히 기억되고 있기 때문이다. 이런 메커니즘을 클로저라고 부른다.

클로저 예시

function outerFn(){
//자유변수
	var x = 10;
//클로저 부분
		var innerFn = function(){console.log(x);
		};
	return innerFn
};

var inner = outerFn();
inner();   //10

inner라는 변수에 outerFn() 을 실행시키면 innerFn이 리턴된다.

그 후에, inner()를 다시 실행시키면 innerFn이 실행되는데 이 때가 클로저 부분이다. x 는 자유변수로 outerFn은 소멸되었지만 innerFn은 아직 x의 변수에 접근할 수 있다. 그래서 console.log에 10이 찍히게 된다.

클로저는 왜 사용하나요

클로저는 자신이 생성될 때의 환경을 기억한다. 이것은 자바스크립트의 기능으로서 유용하게 사용될 수 있다. 하지만 메모리를 잡아먹는 다는 것에 약간의 단점이 존재한다.

그래서 클로저에서는 메모리에 따른 누수 제거하기가 필요하다. 이것을 가비지 콜렉션이라고 한다.

가비지 콜렉션

"가비지 콜렉션(GC)"이라는 자동 메모리 관리 방법을 사용한다. 가비지 콜렉터의 목적은 메모리 할당을 추적하고 할당된 메모리 블록이 더 이상 필요하지 않게게 되었는지를 판단하여 회수하는 것이다. 이러한 자동 메모리 관리 프로세스는 궁극의 방법은 아니다. 왜냐하면 어떤 메모리가 여전히 필요한지 아닌지를 판단하는 것은 비결정적 문제이기 때문이다.

let fruit = {
	name: "banana"
}

// 여기서 fruit와 apple은 같은 객체를 참조하게 된다.
let apple = fruit;

//근데 여기서 fruit를 null로 지정해 놓으면, apple만 banana를 참조하고 메모리는 유지된다. 
//이때 다시 apple를 다시 fruit와 같다고 한다면 그때 null값으로 바뀐다
fruit = null; 

클로저의 캡슐화

이 방식은 클로저를 사용하여 객체지향 프로그래밍의 정보 은닉을 할 수 있다.
또한 하나의 클로저에서 변수 값을 변경해도 다른 클로저의 값에는 영향을 주지 않는다.

function student(name, score){
	return {
		setScore: function(_score){
			score = _score;
		},
		getInfo: function(){
			return {name:name, score:score};
		}
	}
}

var han = student("danbee", 80);
var kim = student("minji", 70);

kim.setScore(40);

console.log(han.getInfo()); // { name: 'danbee', score: 80 }
console.log(kim.getInfo()); // { name: 'minji', score: 40 }

첫번째 han이라는 변수에 student("danbee", 80)를 실행시켰다.
han에 객체가 담기게 된다.그리고 getInfo를 실행시켜 주었다. getInfo는 {name:name, score:score}을 리턴시킨다. 여기 안에서 클로저가 실행되어서 {name: "danbee", score:80}이라는 결과가 담기게 된다.

두번째로 kim은 점수를 70으로 줬는데 결과 값이 score이 40으로 나왔다.
그 이유는 kim이라는 변수에 담긴 student ("minji", 70)을 했을 땐 {name: "minji", score:70}이 나왔다. 그 후에, kim.setScore(40)을 실행시켜서 setScore(40) 이 들어가게 돼 score:_score(40)이 되었기 때문이다.

이것을 클로저의 은닉화라고도 한다.

0개의 댓글