[JavaScript] 클로저란?

do_large·2020년 11월 25일
1

JavaScript

목록 보기
2/4
post-thumbnail

클로저란?

내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것이다.

  • 클로저는 자신을 포함하고 있는 외부함수의 인자, 지역변수 등을 외부함수가 종료된 이후에도 사용할수 있다. 이러한 변수를 자유변수라고 한다.

  • 클로저가 생성될때 범위 내의 지역변수들을 자유변수로 만드는 것을 캡쳐라고 한다.

function outer (){
	var name = 'dolarge';
  	return function () {
		console.log(name);
    }
}
      
var inner = outer();
inner(); // 'dolarge'

외부함수 outer 안에 return 하는 함수를 보면 outer 내부변수인 name을 출력하는 함수이다.
여기서 name이 자유변수이다. inner변수는 outer를 실행한 결과인 함수를 받게되는데 inner를 실행하게 되면 값이 제대로 출력되는것을 볼수있다. 즉, outer함수 실행이 종료된 이후에도 참조된 name변수는 사라지지않고 제대로된 값을 반환하고 있다.

클로저를 통한 은닉화

클로저를 사용하여 외부에서 변수에 직접 접근하는 것을 제한할 수 있다. 즉 자유변수를 객체지향언어의 private 멤버변수처럼 사용한다. (은닉화)

function factory_movie(title){
    return {
        get_title : function (){
            return title;
        },
        set_title : function(_title){
            title = _title
        }
    }
}

var ghost = factory_movie('Ghost in the shell');
var matrix = factory_movie('Matrix');
 
alert(ghost.get_title()); // 'Ghost in the shell'
alert(matrix.get_title()); // 'Matrix'
 
ghost.set_title('공각기동대');
 
alert(ghost.get_title()); // '공각기동대'
alert(matrix.get_title()); // 'Matrix'

factory_movie의 지역변수 title에는 set_title메서드를 통해서만 값을 설정할수있다.
값을 읽고 수정할 수 있는방법은 factory_movie의 메서드를 통해서 만들어진 객체를 사용해야 한다.

반복문에서 클로저 사용하기

var arr = []
for(var i = 0; i < 5; i++){
    arr[i] = function(){
        return i;
    }
}

for(var index in arr) {
    console.log(arr[index]());
}

// 실행결과 5 5 5 5 5

console.log()가 작동하는 시점에서 i값은 5이기때문에 0 1 2 3 4가 아니라 5만 출력된다


IIFE(즉시실행함수표현)을 사용해서 원하는 대로 만들수있다.
즉시실행함수의 인자로 i를 넣어주게 되면 외부함수의 id에 i값이 복사되고 자유변수인 id는 for문이 작동하는 시점의 i값을 가지게 된다. 그래서 실행결과가 0 1 2 3 4인것을 볼수있다.

var arr = []
for(var i = 0; i < 5; i++){
    arr[i] = function(id) {
        return function(){
            return id;
        }
    }(i);
}
for(var index in arr) {
    console.log(arr[index]());
}

// 실행결과 0 1 2 3 4 

클로저의 성능

클로저는 각각의 자유변수를 계속 참조하고 있기때문에 참조를 제거해주지 않으면 메모리가 소모될것이다. 그래서 클로저 사용이끝나면 참조를 제거하는것이 좋다.

function factory_movie(title){
    return {
        get_title : function (){
            return title;
        },
        set_title : function(_title){
            title = _title
        }
    }
}

var ghost = factory_movie('Ghost in the shell');
var matrix = factory_movie('Matrix');
 
alert(ghost.get_title()); // 'Ghost in the shell'
alert(matrix.get_title()); // 'Matrix'

// 메모리를 release 시키기 위해 클로저의 참조를 제거함
ghost = null;
matrix = null;

참고
https://hyunseob.github.io/2016/08/30/javascript-closure/
https://jhleed.tistory.com/150
https://offbyone.tistory.com/135
https://opentutorials.org/course/743/6544

0개의 댓글