2012-07-27 58 views
3

我正在研究一個jQuery插件,它允許您記錄任何javascript類或對象。 這個想法是重寫對象內的每個函數或函數的原型。jQuery記錄器插件

(function($) 
{ 
    "use strict"; 

    $.log = function(object, logger) 
    { 
     if (!$.isFunction(logger)) 
     { 
      logger = function(name, args) 
      { 
       console.log(name + "(" + $.makeArray(args).join(", ") + ")"); 
      }; 
     } 

     var s = $.isFunction(object) ? object.prototype : object; 

     for (name in s) 
     { 
      var fn = s[name]; 

      if ($.isFunction(fn)) 
      { 
       s[name] = (function(name, fn) 
       { 
        return function() 
        { 
         logger(name, arguments); 
         return fn.apply(this, arguments); 
        }; 
       })(name, fn); 
      } 
     } 
    }; 
})(jQuery); 

這似乎適用於記錄單個插件。例如$.log($.ui.tabs);記錄了標籤原型中的所有函數調用。

但是,當我想記錄所有的jQuery $.log($);它給我一些參考錯誤。 我想不通爲什麼我得到這個錯誤。我的印象是它與this或傳遞的參數有關,但我不確定。

編輯:現在我想一想更多它也可能是因爲重寫的函數總是返回而引起的。

我創建了一個小提琴試玩問題:http://jsfiddle.net/Sj6xN/4/

編輯:

這是我最終的代碼,到目前爲止正常使用:

(function($) 
{ 
    "use strict"; 

    var Logger = function(options) 
    { 
     this.options = $.extend(this.defaults, options); 
    }; 

    Logger.prototype = { 
     defaults: 
     { 
      inherited: false, 
      deep: false, 
      logWriter: function(name, args) 
      { 
       console.log("CALL: " + name + "(" + $.makeArray(args).join(", ") + ")"); 
      } 
     }, 
     augment: function(object) 
     { 
      var self = this; 

      // Make sure this object is not already augmented 
      if (object.__isAugmented__) 
      { 
       return; 
      } 

      // Set 'isAugmented' to prevent recursion 
      object.__isAugmented__ = true; 

      // Loop through the object 
      for (var name in object) 
      { 
       var originalFunction = object[name]; 

       // If it's a function and the function is not inherited or 'inherited' is enabled augment it 
       if ($.isFunction(originalFunction) && (object.hasOwnProperty(name) || self.options.inherited)) 
       { 
        // Wrap in self executing function so references to 'name' and 'orginalFunction' are maintained 
        object[name] = (function(name, originalFunction) 
        { 
         // If the function has a prototype and 'deep' is enabled augment that as well 
         if (self.options.deep && originalFunction.prototype) 
         { 
          self.augment(originalFunction.prototype); 
         } 

         var augmentedFunction = function() 
         { 
          // Execute log writer 
          self.options.logWriter(name, arguments); 

          // Call original function 
          return originalFunction.apply(this, arguments); 
         }; 

         // Inherit prototype of original function 
         augmentedFunction.prototype = originalFunction.prototype; 

         // Return the augmented function 
         return augmentedFunction; 
        })(name, originalFunction); 
       } 
       // If it's a plain object and 'deep' is enabled augment that as well 
       else if (self.options.deep && $.isPlainObject(originalFunction)) 
       { 
        self.augment(originalFunction); 
       } 
      } 
     } 
    }; 

    $.log = function(object, options) 
    { 
     var logger = new Logger(options); 

     // If the object is a function use it's prototype, otherwise assume a plain object 
     object = $.isFunction(object) ? object.prototype : object; 

     // Augment 
     logger.augment(object); 
    }; 
})(jQuery); 

可用於像這樣:

$.log(<object or function> [, 
{ 
    inherited: <bool>, 
    deep: <bool>, 
    logWriter: <function(name, args)> 
}]); 

回答

1

仔細查看錯誤。

Uncaught ReferenceError: name is not defined 

說明你還沒有定義的名稱和因爲你是在strict mode,你不能沒有定義它(通常如果你這樣做,這將是一個全局變量,而不是嚴格使用變量模式)。所以如果你在它之前寫了一個var name,你不會再遇到這個錯誤。

雖然沒有選項卡方法有另一個錯誤。另一個錯誤說tabs不是對象的方法,這是因爲當你包裝函數時,你沒有繼承原型,所以當函數被新的調用時,它沒有原型函數(tabs是他們)。

這裏的固定代碼:http://jsfiddle.net/Sj6xN/8/

+0

未申報的'name'變量是很明顯的,我沒有得到這個錯誤,雖然,'name'是window'的'屬性所以它的聲明。你是怎麼得到這個錯誤的?完全忘記了原型繼承,謝謝!我不能投你的答案,因爲我沒有足夠的聲譽。 – Shikyo 2012-07-30 12:52:04

+0

你可以「接受」我的答案,你不需要聲譽。 'name'是window的屬性,如果你已經定義了它的範圍,這不是一件好事,你不應該在這裏使用它,或者你是js解釋器不完全支持「嚴格模式」。 – 2012-07-30 13:23:54

+0

我在firefox的首頁測試了名稱variabele,它仍然被聲明。不要在任何地方看到「接受」按鈕,但將其標記爲有用。 – Shikyo 2012-07-30 17:10:41