'closures'에 해당되는 글 3건

  1. 2007.08.12 Lazy Function Definition Pattern
  2. 2007.05.17 closures
  3. 2006.08.27 Closures JavaScript
오늘 Lazy Function Definition Pattern 이란 글을 읽었는데 도움이 될것 같아 정리해둔다.

Lazy Function Definition Pattern은 많은 언어도 있지만 늦은 초기화랑 비슷하다.
필요할때 생성하고 그 이후에는 재활용하는것을 말한다.

피터씨는  이와 같은 패턴을 Lazy Function Definition Pattern이라고 한다.
자바스크립트에서 이 기법을 구현하는데는 많은 방법이 있는데 여기에서는 4가지 방법을 소개하고 최적의 방법을 알려 준다.

문제는, foo라는 함수는 호출을 하면 data객체를 반납하는데 처음에 호출시에만 date를 생성하고 다음 호출에는 재활용해야한다. 이러한 foo함수를 만드는것 문제이다.

1.고전 적인 방법.


var t;
function foo(){
    if(t){
       return t;
    }
    t = new Date();
    return t;
}

이 방법에는 두가지 문제가 있다.
첫번째는 여분의 t라는 글로벌 변수를 사용해야 한다.
두번째는 실행시 코드가 최적화 되어있지 않다. 즉 매번 if문을 실행 해야한다.

2.묘듈 패턴.(The Module Pattern)

var foo = (function() {
    var t;
    return function() {
        if (t) {
            return t;
        }
        t = new Date();
        return t;
    }
})();

묘듈 패턴으로 첫번째 문제는 해결할수 있다.클로우져(closure) 이용하여 글로벌 변수 t를 숨기고  오직 foo에서만 사용할수 있게 했다.
하지만 이 패턴으로는 두번째 문제를 해결할수 없다. 좋은 패턴이긴 하지만 여기에서는 유용하지 않다.

3.함수는 오브젝트(Functions are Objects)
function foo() {
if (foo.t) {
return foo.t;
}
foo.t = new Date();
return foo.t;
}
자바스크립트에서는 모든 함수는 오브젝트이다. 그렇기 때문에 프로퍼트를 가질수 있고 위와 같은 방법을 사용할수 있다. 이 방법은 매우 깔끔하고 보기는 좋은나 여전히 두번째 문제는 조건절을 해결하지 못했다.
(이 방법은 원래 있던 프로퍼티를 있는 듯 사용하고 있어서 나중에 모르는 사람이 봤을때 많이 헤갈리는것 같았다. 개인적으로 비추.)

4. Lazy Function Definition
이글의 저자인 피터씨가 추천하는 방법이다.

var foo = function() {
    var t = new Date();
    foo = function() {
        return t;
    };
    return foo();
};

이 방법의 원리는 클로우져를 이용한 방법이다.
처음 foo를 실행했을때 처음 t에 Date가 할당되고 foo함수에 클로우져가 할당되고 Date를 반환한다. 그 다음 호출할때는 foo에 할당된 클로우져를 호출하여 바로 Date를 반환한다.
이 방법이 이해가 되지 않는다면 이글을 참조하면 될것 같고 하지만 이글과 다른게 이 방법은 의도적으로 사용했다는 점이다.
Posted by 전용우

closures

프로그래밍 2007.05.17 18:27
저번에 javajigi에서 발표할때가 있었다.
closure설명을 하다가 질문 중 하나가  "ajax in action에서 closure를 사용하면 메모리가 회수가 안된다.그래서 가능하면 사용하지 말라고 했다. 왜 그러냐?"는 질문이 있었는데.
나의 대답은 "순환관계일경우 회수가 안된다"라고 말했던것으로 생각한다.

그 당시 말 뜻을 잘 전달을 못한것 같아 다시 정리를 해보면 아래와 같은 경우를 말한것 같다.

function test(){
  var val = 5;
  function plusAlter(){
   alert(val);
  }
  return plusAlter;
}
var plusAlter = test();
plusAlter(); ->"5"

이와 같은경우 메모리 누수 현상이 발생된다.

이유는 함수(test)안에서 함수(plusAlter)를 선언하고 자신의 함수(plusAlter)의 context말고 상위(text)의 프로퍼티를 사용할수 있다.하지만 deep copy가 아니고 pointer를 가지고 있다.
그래서 plusAlter에서 상위(test)를 프로퍼트(val)을 사용(참조)하기 때문에 test()를 사용한 후에 GC에서 메모리를 회수를 안한다.그렇기 때문에 이런경우 매모리 누수가 일어난다.
(GC는 누군가 참조하고 있으면 회수안함.)

그래서 아래와 같이 prototype을 이용하여 수정해서 쓰기를 ajax in action에서 권장한다.

function test(){
  this.val = 5;
}
test.prototype.plusAlter = function(){
  alert(this.val);
}

var freeleak = new test();
freeleak.plusAlter(); ->"5"

Posted by 전용우
참고로 난 아는언어는 Java밖에 없습니다..(사실은 자바도 허우덕 되고 있슴..ㅜ.ㅜ)
그래서 closures가 헤갈립니다.:)
하지만 현재 java jdk7버전부터 Closures가 지원될지도 모른다는 토비님의 포스팅을 보구
Closures을 잘몰라서  공부하기 시작했습니다.
(아직도 잘 이해가..영어를 잘해야겠다는 생각을 다시하게하는 하루였음)

What this means is that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.

간단히 설명하면 inner function에서 outer function의 var,parameter를 접근하는것,outer function에서 return되었을때 조차도 var,parameter를 접근하는것을 말합니다.


참고 사이트
Closures JavaScript

javascript tip
Private static members in JavaScript
Understanding and Solving Internet Explorer Leak Patterns
JavaScript Closures
Javascript Closures
Leak Free Javascript Closures
Ecma-262
Posted by 전용우