我正在尝试使用不同级别(调试,信息,警告...)对具有不同属性(如颜色,名称等)的自定义记录器进行原型设计。
我要做的是动态构建所有这些级别,从存储所有属性的Hashmap中获取它们。
例如,我的自定义记录器对象包含logger.debug('test')
,logger.info('text)
,依此类推。你明白了。
但是,我遇到了这个特殊代码的问题:
var MyLogger = function(opts) {
this.level = opts.level || 0
this.loggers = {}
var self = this
for (l in LEVELS) {
this.addLogger(l, new loggerOutput(LEVELS[l]))
this[l] = function(message) {
self.getLogger(l).output(message)
}
}
}
问题在于 self.getLogger(l),因为它始终指向我的上一个记录器(ERROR)。如果我用静态字符串替换变量,它可以工作: self.getLogger('info')
解决方法是手工制作所有记录器的原型,并且显而易见,但是我希望找到更好的解决方案:
MyLogger.prototype = {
debug: function(message) {
this.getLogger('debug').output(message)
},
info: function(message) {
this.getLogger('info').output(message)
}
...
}
提前谢谢。
答案 0 :(得分:1)
使用原型解决方案,但通过将当前“级别”传递给函数工厂来循环分配函数。
for (var L in LEVELS)
MyLogger.prototype[L] = loggerMaker(L)
function loggerMaker(l) {
return function(message) {
this.getLogger(l).output(message)
};
}
这里我使用了一个函数来创建一个新的变量作用域,它引用循环中的当前L
。
如果您只编码现代JavaScript环境,我会使用数组而不是Object来保存关卡,然后使用forEach
和匿名函数。
;['debug','info','warn'].forEach(function(L) {
MyLogger.prototype[L] = function(message) {
this.getLogger(L).output(message);
};
});