함수프로퍼티 - 메모이제이션(Memoization)패턴
함수는 객체이기 때문에 프로퍼티를 가질 수 있다. 사실 함수는 생성될 때부터 프로퍼티와 메서드를 가지고 있다. 그 예가 length다. length는 함수가 받는 인자의 개수를 값으로 가진다.function func(a, b, c) {} console.log(func.length); // 3언제들지 함수에 사용자 정의 프로퍼티를 추가할 수 있다. 함수에 프로퍼티를 추가하여 결과(반환 값)을 캐시하면 다음 호출 시섲ㅁ에 복잡한 연산을 반복하지 않을 수 있다. 이런 방법을 메모이제이션 패턴이라고 한다.
var myFunc = function(param) { if (!myFunc.cache[param]) { var result = {}; //... 비용이 많이 드는 수행 ... myFunc.cache[param] = result; } return myFunc.cache[param]; }; //캐시 저장공간cache 프로퍼티는 함수로 전달된 param 매개변수를 키로 사용하고 계산의 결과를 값으로 가지는 객체(해시)다. 위 코드의 문제는 myFunc함수가 단 하나의 매개변수를 받는다고 가정하고 있다. 게다가 이 매개변수는 문자열과 같은 원시 데이터 타입이라고 가정한다.
더 많은 매개변수와 복잡한 타입을 갖는다면 어떻게 해야 할까? (직렬화하여 해결한다.)
var myFunc = function() { var cachekey = JSON.stringify( Array.prototype.slice.call(arguments)), result; if (!myunc.cache[cachekey]) { result = {}; //비용이 많이 드는 수행... myFunc.cache[cachekey] = result; } }; // 캐시 저장공간 myFunc.cache = {};직렬화하면 객체를 식별할 수 없게 되는 것을 주의하라. 만약 같은 프로퍼티를 가지는 두 개의 다른 객체를 직렬화하면, 이 두 객체는 같은 캐시 항목을 공유하게 될 것이다.
이 함수를 작성하는 다른 방법으로는 하드코딩 대신 arguments.callee를 사용해 함수를 참조할 수 있다. (하지만 곧 사라질 운명이다. 쓰지 않는 것이 낫다. 명심)
var myFunc = function (param) { var f = arguments.callee, result; if (!f.cache[param]) { result = {}; //...비용이 많이 드는 수행... f.cache[param] = result; } return f.cache[param]; }; // 캐시 저장공간 myFunc.cache = {}; };
댓글 없음:
댓글 쓰기