[TIL] 클로저가 뭐지?

kiyeol·2021년 2월 19일
0
post-thumbnail
post-custom-banner

클로저(Closure)가 뭘까?

클로저(Closure) 자바스크립트를 배우면서 언뜻 듣기만 했지, 개념이나 테크닉, 사용법 등은 자세히 몰랐기 때문에 이번 기회에 velog를 통해 정리해보려고 한다.

클로저는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것

function init() {
    var name = "Mozilla"; // name is a local variable created by init
    function displayName() { // displayName() is the inner function, a closure
        alert (name); // displayName() uses variable declared in the parent function    
    }
    displayName();    
}
init();

현재 displayName 이라는 inner 함수에서 name이라는 변수 값이 init() 부모 함수에 선언된 변수를 사용할 수 있다.

클로저를 통한 은닉화

function factory_movie(title){
    return {
        get_title : function (){
            return title;
        },
        set_title : function(_title){
            title = _title
        }
    }
}
ghost = factory_movie('Ghost in the shell');
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 안에 현재 객체 형태인 함수로 get_title과 set_title을 가지고 있다. 이 메소드들은 factory_movie의 인자값으로 전달된 지역변수 title을 사용하고 있다.

get_title -> 외부함수 factory_movie에서 받아온 title을 그대로 리턴
set_title -> 인자로 _title을 받아서 다시 title에 넣어서 반환시킨다.

title에 접근하려면 정의된 객체의 메소드에서만 접근 할 수 있는 값이다.

클로저 반복문

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

i 값은 정의한 함수의 현재 외부 변수 값이 아니기 때문에 5라는 값만 반복해서 나오게 된다.

해결방안

1) 외부 function을 지정하고 외부함수에서 콜백함수가 i를 참조할 때, id라는 외부함수 매개변수를 id라는 값을 이용해 지역 변수를 리턴해준다.

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]());
}

2) Function Scope가 아닌 block scope를 갖는 let을 사용하면 for문 내의 새로운 스코프를 갖기 때문에 매 반복마다 새로운 i가 선언되기 때문에, 반복이 끝난 이후의 값으로 초기화가 된다.

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

참고)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures
https://opentutorials.org/course/743/6544

profile
kyday63@gamil.com
post-custom-banner

1개의 댓글

comment-user-thumbnail
2021년 3월 17일

어 기열님 사진이 있네요? ㅎㅎ

답글 달기