1. Lazy Function Definition Pattern이 필요한 경우
- 특정 값을 계산(또는 실행)을 통해서 얻어와야 하는 경우
- 한 번만 계산(또는 실행)이 되면 그 다음부터는 계산이 필요 없는 경우
- 호출 전까지는 계산(또는 실행)이 될 필요가 없는 경우
Peter님의 예를 보면 Date()를 호출하는 것을 들었습니다.
var t; //global 변수 t를 선언합니다.이 방법으로 쉽게 해결할 수 있지만, 다음과 같은 문제가 존재합니다.
function foo() {
if (t) {
return t; // t의 값이 있는 경우에는 t를 리턴합니다.
}
t = new Date();
return t; // t가 없는 경우에는 t의 new Date()를
// 호출하여 값을 생성한 후 리턴합니다.
}
- foo가 호출될 때마다 if (t)가 호출되어 t에 값이 있는 지 여부를 체크하게 됩니다. (한 번만 체크하면 되는 부분이죠)
- 변수 t가 global로 선언되게 되므로, 불필요한 global 변수가 추가됩니다.
2. Lazy Function Definition Pattern으로 수정하면...
Lazy Function Definition Pattern으로 수정하게 되면 다음과 같은 코드 형태가 됩니다.
var foo = function() {foo의 변화를 alert()을 사용하여 찍어보면 다음과 같습니다.
// foo가 호출될 때 Date를 생성해서 t에 넣습니다.
var t = new Date();
// foo를 closure를 통하여 얻을 수 있는 값 t를 리턴하는 function으로 재정의합니다.
foo = function() {
return t;
}
// foo()가 최초로 실행되도록 호출합니다.
return foo();
}
foo()가 호출되지 않았을 때는 전체 코드를 갖고 있지만,
호출된 후에는 계산된 변수 t의 값만을 갖고 있기 때문에, global 문제와 foo() 호출 시 발생하는 if()코드도 모두 제거할 수 있습니다.
3. 문제점.
var foo = function() {IE에서 위의 코드처럼 a,b,c,d,e가 선언되어 사용된다면, clouser를 사용해서 foo에서 접근할 수 있기 때문에 메모리에서 릴리즈되지 않습니다. 따라서, Memory leak현상이 날 수도 있습니다.
// foo가 호출될 때 Date를 생성해서 t에 넣습니다.
var t = new Date();
var a, b, c, d, e;
// a,b,c,d,e가 선언되어서 여기에서 사용되는 경우
// foo를 closure를 통하여 얻을 수 있는 값 t를 리턴하는 function으로 재정의합니다.
foo = function() {
return t;
}
// foo()가 최초로 실행되도록 호출합니다.
return foo();
}
이를 해결하기 위해서는 clouser로 접근할 수 있는 모든 객체에 대해서 (여기서는 a,b,c,d,e) null처리를 해줘야지만 됩니다.
출처: Lazy Function Definition Pattern via Ajaxian
※ 1의 문제를 해결하기 위한 여러가지 방법이 Lazy Function Definition Pattern에 나와 있으니 한번 읽어보세요.
댓글 없음:
댓글 쓰기