더북(TheBook)

예제 2-25 Aop.js

// 작성자: 프레드릭 아펠버그
// http://fredrik.appelberg.me/2010/05/07/aop-js.html
// 프로토타입을 지원할 수 있게 데이브 클레이턴이 수정함
Aop = {
// 주어진 이름공간에 매칭되는 모든 함수 주변(around)에 어드바이스를 적용한다.
around: function(pointcut, advice, namespaces) {
  // 이름공간이 없으면 전역 이름공간을 찾아내는 꼼수를 쓴다.
  if (namespaces == undefined | | namespaces.length == 0)
    namespaces = [ (function() {return this;}).call() ];
  // 이름공간을 전부 순회한다.
  for (var i in namespaces) {
    var ns = namespaces[i];
    for(var member in ns) {
      if(typeof ns[member] == ‘function’ && member.match(pointcut)) {
        (function(fn, fnName, ns) {
          // member fn 슬롯을 ‘advice’ 함수를 호출하는 래퍼로 교체한다.
          ns[fnName] = function() {
            return advice.call(this, { fn: fn,
                                       fnName: fnName,
                                       arguments: arguments });
            };
          })(ns[member], member, ns);
        }
      }
    }
  },
next: function(f) {
  return f.fn.apply(this, f.arguments);
}
};
 
Aop.before = function(pointcut, advice, namespaces) {
Aop.around(pointcut,
           function(f) {
             advice.apply(this, f.arguments);
             return Aop.next.call(this, f);
           },
           namespaces);
};
 
Aop.after = function(pointcut, advice, namespaces) {
Aop.around(pointcut,
           function(f) {
             var ret = Aop.next.call(this, f);
             advice.apply(this, f.arguments);
             return ret;
           },
           namespaces);
};

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.