2017-12-03 3 views

答えて

0

を作成しますターゲットのプロトタイプのプロパティを列挙します。プロパティーごとに

  1. は、プロパティ記述子を取得します。
  2. メソッド用であることを確認してください。
  3. メソッド呼び出しに関する情報を記録する新しい関数に記述子値をラップします。
  4. 変更されたプロパティ記述子をプロパティに再定義します。

デコレータがプロパティデスクリプタを変更する他のデコレータとうまく機能するように、プロパティデスクリプタを変更することが重要です。

function log(target: Function) { 
    for (const propertyName of Object.keys(target.prototype)) { 
     const descriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyName); 
     const isMethod = descriptor.value instanceof Function; 
     if (!isMethod) 
      continue; 

     const originalMethod = descriptor.value; 
     descriptor.value = function (...args: any[]) { 
      console.log("The method args are: " + JSON.stringify(args)); 
      const result = originalMethod.apply(this, args); 
      console.log("The return value is: " + result); 
      return result; 
     }; 

     Object.defineProperty(target.prototype, propertyName, descriptor);   
    } 
} 

基本クラスのメソッド

あなたはこれが同様に、基本クラスのメソッドに影響を与えるようにしたい場合は、あなたがこれらの線に沿って何かをしたいかもしれませんが:

function log(target: Function) { 
    for (const propertyName in target.prototype) { 
     const propertyValue = target.prototype[propertyName]; 
     const isMethod = propertyValue instanceof Function; 
     if (!isMethod) 
      continue; 

     const descriptor = getMethodDescriptor(propertyName); 
     const originalMethod = descriptor.value; 
     descriptor.value = function (...args: any[]) { 
      console.log("The method args are: " + JSON.stringify(args)); 
      const result = originalMethod.apply(this, args); 
      console.log("The return value is: " + result); 
      return result; 
     }; 

     Object.defineProperty(target.prototype, propertyName, descriptor);   
    } 

    function getMethodDescriptor(propertyName: string): TypedPropertyDescriptor<any> { 
     if (target.prototype.hasOwnProperty(propertyName)) 
      return Object.getOwnPropertyDescriptor(target.prototype, propertyName); 

     // create a new property descriptor for the base class' method 
     return { 
      configurable: true, 
      enumerable: true, 
      writable: true, 
      value: target.prototype[propertyName] 
     }; 
    } 
} 
関連する問題