본문 바로가기

Programming/Javascript

15. Javascript 함수형 프로그래밍 적용(3) - wrapper

javascript logo image

 

 

Javascript의 wrapper(래퍼) 함수는 간단하게 말해 다른 OOP 언어들의 다형성을 구현하는 '오버라이드(override)' 기능과 동일하다고 생각하면 됩니다. 여기서는, original이라는 원본 함수가 있는데, 여기에 다른 익명의 함수를 대입해 실행하게 만드는 예제를 생성해 보도록 하겠습니다.

 

function wrap(object, method, wrapper) {
    // 이 예제에서는, fn = Function.prototype.original
    var fn = object[method];

    return object[method] = function() {
        return wrapper.apply(this, [fn].concat(Array.prototype.slice.call(arguments)));
    }
};

/* original 함수를 호출한 객체의 value프로퍼티에는 
    파라미터 value가 대입되고, 이 값이 출력된다.*/
Function.prototype.original = function(value) {
    this.value = value;
    console.log("value : " + this.value);
};

var mywrap = wrap(Function.prototype, "original", function(orig_func, value){
    this.value = 20;
    orig_func(value);
    console.log("wrapper value : " + this.value) ;
});

var obj = new mywrap("SWINGS");

/* 출력
value : SWINGS
wrapper value : 20
*/

 

여기서 구조를 살펴보면, wrap 함수의 세 번째 파라미터에는 임의의 익명함수가 전달되었습니다. 이 익명함수로 기존 original 함수를 덮어쓰게 됩니다. 래퍼를 통해 새로 실행되는 함수의 경우에는, 첫 번째 파라미터에 기존의 원본 original 함수를 전달하여(orig_func) 원본 함수를 한 번 실행하고, 새로운 함수의 결과 값을 출력하도록 설정하였습니다. 이 원본 함수의 출력 방식은 복잡해 보이지만 차근차근 읽어보면 쉽게 이해할 수 있습니다.

 

우선, wrapper를 apply를 통해 실행할 때, this를 this로 바인딩한 다음 두 번째 파라미터에서 concat을 통해 인자를 통합된 배열로 인자를 전달하고 있습니다. 이때, concat을 통해 통합하는 첫 번째 인자는 [fn]으로 정의되어 있습니다. 즉, original 함수 자체에 해당 함수 실행 시에 전달되는 기본 인자가 concat으로 합쳐져 배열이 되는 것입니다. 

 

wrap 함수가 실행되어 mywrap으로 리턴되는 라인에서 보면, 새로 정의되는 익명함수는 두 개의 파라미터를 갖고 있습니다. 그럼 결과적으로 concat을 통해 생성된 배열인자의 인덱스 순서대로 orig_func에는 변수 fn으로 정의된 프로토타입 함수가 들어가고, value에는 "SWINGS"가 전달됩니다. 이러한 과정을 통해, 원본 value인 SWINGS와 wrapper value인 20이 순차적으로 출력되는 구조를 만들 수 있습니다.