[자바스크립트] 클로저

June·2021년 8월 12일
0

클로저

클로저는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. 클로저는 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용된다.

내부 함수

자바스크립트는 함수 안에서 또 다른 함수를 선언할 수 있다. 아래의 예제를 보자. 결과는 경고창에 coding everybody가 출력될 것이다.

function outer() {
  function inner() {
    var title = "coding everybody";
    alert(title);
  }
  inner();
}
outer();

위의 예제에서 함수 outer의 내부에는 함수 inner가 정의되어 있다. 함수 inner를 내부 함수라고 한다.

내부함수는 외부함수의 지역변수에 접근할 수 있다. 아래의 예제를 보자. 결과는 coding everybody이다.

함수 안에다 함수를 선언하는 이유는, 그 외부 함수에서만 사용하는 함수면 내부에 두는 것이 응집성이 높기 때문이다.

여기서 var title은 외부함수에 정의되어있는 지역변수이다. 내부 함수에서 변수를 사용하려하는데, 내부함수에서 존재하지 않으면 외부함수에서 찾는다.

클로저

클로저(closure)는 내부함수와 밀접한 관계를 가지고 있는 주제다. 내부함수는 외부함수의 지역변수에 접근할 수 있는데 외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근할 수 있다. 이러한 메커니즘을 클로저라고 한다. 아래 예제는 이전의 예제를 조금 변형한 것이다. 결과는 경고창으로 coding everybody를 출력할 것이다.

function outter() {
  var title = "coding everybody";
  return function() {
    alert(title);
  }
}
inner = outter();
inner();

조금 더 실용적인 예제

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());
alert(matrix.get_title());

ghost.set_title("공각기동대");
alert(ghost.get_title()); // 공각기동대
alert(matrix.get_title()); // Matrix

반환하는 객체 안에 함수가 정의되어있는 모양인데, 이것도 내부함수이다. 매개변수(title)은 함수 내에서 지역변수로 사용되고, 지역변수는 내부함수에서 접근 가능하기 때문에, get_title은 외부함수의 매개변수로 들어온 값을 반환한다.

set_title 메서드는 지역변수 title을 변경하게 된다.

이제 title 지역변수는 get_title과 set_title을 통해서만 접근 가능하게되므로 private 변수가 된다.

클로저 관련 자주하는 실수

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

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

0부터 4까지 출력할 것이라 기대했지만 5만 다섯 번 나왔다. i의 값이 함수의 외부 변수의 값이 아니기 때문이다

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

이것이 외부함수가 되고, 매개변수로 i를 준 것이다. for문을 돌 때마다 외부 함수가 실행이 되고, id의 매개변수로 i를 받아서 전잘한다. 내부 함수를 리턴하는데, 내부함수는 외부함수의 지역변수인 id를 쓰고 있는 상황이다.

0개의 댓글