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)>
}]);

Antworten auf die Frage(1)

Ihre Antwort auf die Frage