0

我正在尝试对具有不同级别(调试、信息、警告...)的自定义记录器进行原型设计,每个记录器都具有不同的属性,如颜色、名称等。

我要做的是动态构建所有这些级别,从我存储所有属性的 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),因为它总是指向我的最后一个记录器(错误)。如果我用静态字符串替换变量,它可以工作:self.getLogger('info')

解决方法是手动制作所有记录器的原型,并且显然可行,但我期待找到更好的解决方案:

MyLogger.prototype = {
    debug: function(message) {
        this.getLogger('debug').output(message)
    },
    info: function(message) {
        this.getLogger('info').output(message)
    }
        ...
}

先感谢您。

4

1 回答 1

1

使用原型解决方案,但通过将当前“级别”传递给函数工厂来循环分配函数。

for (var L in LEVELS)
    MyLogger.prototype[L] = loggerMaker(L)

function loggerMaker(l) {
    return function(message) {
        this.getLogger(l).output(message)
    };
}

在这里,我使用了一个函数来创建一个新的变量作用域,该作用域引用L循环中的当前变量。

如果您只为现代 JavaScript 环境编写代码,我会使用 Array 而不是 Object 来保存关卡,然后forEach与匿名函数一起使用。

;['debug','info','warn'].forEach(function(L) {
    MyLogger.prototype[L] = function(message) {
        this.getLogger(L).output(message);
    };
});
于 2012-05-25T14:11:21.480 回答