RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR

 Javascript의 모듈 패턴(Module Pattern)을 이해하기 위해서 선행학습이 필요한 Closure 개념을 나름대로 정리해 보았습니다.

 우선 Closure를 이해하기 위해서는 아래 내용들의 사전 학습이 필요합니다. 아래 글은 기본적인 개념을 이해하고 있다는 가정하에 작성되었습니다.

  • 유효범위(Scope)
  • 가비지 컬렉셔(Gabage Collection, 이하 GC)
  • 이름없는 함수(Anonymous function)
  • Javascript에서 function은 object로 처리됩니다. (이는 GC의 정리 대상 여부와 관련이 됩니다.)

정 의

 클로저(Clousure)는 자신의 유효범위(Scope) 외의 변수들을 참조할 수 있는 정보를 가지는 참조 환경(referencing environment)을 가지는 함수또는 함수의 참조이다.

Wikipedia in Closure (computer programming)

위의 정의는 일반적인 프로그래밍에서의 클로저(Closure)정의이기에 조금 명확하지 않은데, Javascript에서는 아래와 같이 해석할 수 있습니다.

 자바스크립트에서 클로저는 함수의 생명주기는 끝이났지만 함수내의 변수를 내부함수가 참조하고 있기 때문에 유지되어 접근할수 있는 함수이다.

Outsider in 자바스크립트 클로저(Closure)에 대해서...

간단한 예제

클로저(Closure)의 간단한 예제를 살펴 봅시다. 호출 할 때마다 1부터 시작하는 연속적인 수를 반환하는 함수입니다.

var sequencer = function() {
  var count = 0;
  return function() {
      return ++count; 
  }
};

var seq = sequencer();

seq(); // 1
seq(); // 2
seq(); // 3

 일반적인 언어에서 보기 힘든 문법을 확인 할 수 있습니다. function을 호출했더니 function을 반환합니다. 또한 반환된 함수를 호출 할 때마다, 자신의 유효범위(scope)에 해당하지 않는 count를 지속적으로 사용해서 count에 1을 더하고 이 값을 반환하는 것을 확인할 수 있습니다.

 sequencer() 가 호출되는 시점에 count의 생명주기는 끝나기 때문에 count는 GC에 의해서 정리가 되어야 하는데 어떻게 count가 계속 유효할가요?

 javascript의 function이 object라는 사실을 생각하면 좀 더 쉽게 생각할 수 있습니다. 왜냐하면 sequencer()가 호출 될 때 function(object)[seq()]이 반환되는데, 이 function(object)이 count 변수를 참조하고 있기때문에 비록 count 변수를 정의한 function[sequencer()]의 생명주기가 끝났지만 count의 참조가 유효하기 때문에 GC에 의해서 정리가 되지 않기 때문입니다. 이 말은 다르게 생각하면 메모리 릭이 발생할 수 있는 포인트라서 조심해야 하는 부분이 됩니다.

조금은 복잡한 예제

위의 예제로 이해가 되지 않는다면 아래 코드 및 결과를 바탕으로 이해를 해보시면 될 것 같습니다.

var sequencer = function(base) {
  var count = base;
  return function() {
      return ++count; 
  }
};

var base_0_seq = sequencer(0);
var base_5_seq = sequencer(5);

base_0_seq(); // 1
base_0_seq(); // 2
base_5_seq(); // 6
base_5_seq(); // 7
base_0_seq(); // 3

성 능

성능과 관련된 글을 MDN에 잘 정리되어 있어서 참조를 했습니다.

클로져가 필요하지 않은 작업인데도 함수안에 함수를 만드는 것은 스크립트 처리 속도와 메모리 사용량 모두에서 현명한 선택이 아니다.

예를들어 새로운 오브젝트나 클래스를 만들 때 오브젝트 생성자에 메쏘드를 정의하는 것 보다 오브젝트의 프로토타입에 정의하는것이 좋다. 오브젝트 생성자에 정의하게 되면 생성자가 불릴때마다 메쏘드가 새로 할당되기 때문이다.

jaemin_jo in MDN 클로져(Closure)

나쁜 예는 method 정의가 function object 생성때 마다 발생하지만, 아래 좋은 예에서는 상속된 속성은 모든 object에서 사용할 수 있고 method정의가 function object 새성 때 마다 일어나지 않습니다.

나쁜 예

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

좋은 예1

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype = {
  getName: function() {
    return this.name;
  },
  getMessage: function() {
    return this.message;
  }
};

좋은 예2

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

결 론

클로저(Closure)는 언듯보면 유효범위(Scope)에 맞지 않는 동작을 보이는 듯 하나, 가비지 컬렉션(Gabage Collection)과 Javascript에서 function은 object라는 점을 고려하면 자연스러운 동작인 것을 확인 할 수 있습니다.

개인적으로 나중에 제가 읽고 다시 이해할 정도로 클로저(Closure)를 정리하다보니 내용이 많이 부족하네요. 혹시 이해가 안되시면 댓글을 남겨주시면 내용을 추가하거나 아는한도 내에서 답변을 해드리겠습니다. (Javascript는 초보라서 사실 위에 내용도 정확한지 잘 모르겠네요;;;) 또한 아래 제가 읽은 좋은 글들을 링크해 두었으니 참조하시면 될 것 같습니다.

참고자료

MDN 클로져(Closures)
HTML5JS에서 발표한 Closure와 Scope Chain
Closure in javascript (자바스크립트에서 클로져는 무엇인가?)
자바스크립트 클로저(Closure)에 대해서...
자바스크립트의 클로저 (JavaScript's Closure)
[번역] Explaining Javascript Scope and Closure

'Dev > JavaScript' 카테고리의 다른 글

Node.js, npm(Node Package Manager) 설치  (1) 2014.04.19

Trackback
Reply
Moss:
Root (119)
Dev (14)
Life (29)
Programming (2)
Music (2)
Android (4)
Tip (2)
Java (11)
Creative (3)
Lyrics (2)
Windows 7 (2)
Etc (7)
C# (8)
Spring (1)
jQuery (2)
Web (4)
Travel (10)
Cook (0)
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30