2012-07-27 56 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