Javascript jquerylogger插件
我正在开发一个jQuery插件,它允许您记录任何javascript类或对象。 其思想是覆盖对象或函数原型中的每个函数Javascript jquerylogger插件,javascript,jquery,logging,plugins,Javascript,Jquery,Logging,Plugins,我正在开发一个jQuery插件,它允许您记录任何javascript类或对象。 其思想是覆盖对象或函数原型中的每个函数 (function($) { "use strict"; $.log = function(object, logger) { if (!$.isFunction(logger)) { logger = function(name, args) {
(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($)代码>它给了我一些参考错误。
我不明白为什么我会犯这个错误。我觉得这与这个
或者传递的参数有关,但我不确定
编辑:现在我再考虑一下,这可能是因为重写的函数总是返回
我创建了一个小提琴来演示这个问题:
编辑:
这是我最后得到的代码,到目前为止工作得很好:
(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)>
}]);
$.log([,,
{
继承:,
深:,
日志作者:
}]);
我们仔细查看错误
Uncaught ReferenceError: name is not defined
这意味着您尚未定义名称,并且由于您处于中,因此在未定义变量的情况下无法使用该变量(通常,如果您这样做,它将是一个全局变量,但不是在严格模式下)。因此,如果在它之前写一个var name
,就不会再出现这个错误
虽然没有tab方法还有另一个错误。另一个错误是,tabs
不是对象的方法,这是因为当您包装函数时,您没有继承原型,因此当使用new调用函数时,它没有原型函数(tabs
是其中之一)
下面是固定的代码:未声明的name
变量非常明显,但是我没有发现这个错误,name
是window
的属性,所以声明了它。你怎么会犯这个错误的?完全忘记了原型继承,谢谢!我不能投票支持你的答案,因为我没有足够的声誉。你可以“接受”我的答案,你不需要声誉。name
将是window的属性,如果您在这个范围之外定义了它,这不是一件好事,您不应该在这里使用它,或者您的js解释器不完全支持“严格模式”。我在firefox的startpage上测试了Variable的名称,它仍然被声明。在任何地方都看不到“接受”按钮,但将其标记为有用。是的。它没有加入firefox,但加入了chrome。不知道为什么。“接受”按钮就在向上投票的下方,即空勾号。