jQuery Logger Plugin
Ich arbeite an einem jQuery-Plugin, mit dem Sie jede Javascript-Klasse oder jedes Objekt protokollieren können. Die Idee ist, jede Funktion innerhalb des Objekts oder den Prototyp einer Funktion zu überschreiben.
(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);
Dies scheint für die Protokollierung einzelner Plugins zu funktionieren. Zum Beispiel$.log($.ui.tabs);
protokolliert alle Funktionsaufrufe innerhalb des Registerkartenprototyps.
Aber wenn ich alles von jQuery protokollieren will$.log($);
es gibt mir einen Referenzfehler. Ich kann nicht herausfinden, warum ich diesen Fehler erhalte. Ich habe den Eindruck, es hat auch etwas damit zu tunthis
oder die Argumente übergeben werden, aber ich bin nicht sicher.
Edit: Jetzt überlege ich es mir noch etwas, es könnte auch daran liegen, dass die überschriebene Funktion immer zurückkehrt.
Ich habe eine Geige erstellt, um das Problem zu demonstrieren:http://jsfiddle.net/Sj6xN/4/
BEARBEITEN:
Dies ist der Code, mit dem ich am Ende fertig war und der bisher perfekt funktioniert hat:
(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);
Kann so verwendet werden:
$.log(<object or function> [,
{
inherited: <bool>,
deep: <bool>,
logWriter: <function(name, args)>
}]);