3

我有一个基本问题如下:

我在同一个目录中有 2 个单独的模块 main.js 和 logger.js。logger.js 很简单:

function Logger(){
    return this;
};

Logger.prototype.log = function(str) {
    console.log('[' + this.mPrefix + ']' + str);
};

Logger.prototype.init = function(pr){
    this.mPrefix = pr;
}
module.exports = Logger;

现在,我想在主模块中使用我的记录器,如下所示:

var logger = require('./logger.js');
logger.init('MAIN');

logger.log('foo');

但 node 坚持认为Logger没有名为initor的方法log。我也试过require('./logger.js')()了,因为我传递了一个返回 self 对象的函数,但它没有帮助。在其他模块中定义对象并导出它们的最佳实践是什么?顺便说一句,它恰好通过这样做起作用:

var logger = require('./logger.js');
var l = new logger();
l.init('MAIN');
l.log('bar');

然而,这对我来说似乎很笨拙。有什么解释和建议吗?

4

2 回答 2

15

你有一个构造函数;这就是prototype目的。如果你想要一个全局记录器对象,你需要导出一个全局记录器对象:

var logger = {};

logger.log = function(str) {
    console.log('[' + logger.mPrefix + ']' + str);
};

logger.init = function(pr) {
    logger.mPrefix = pr;
};

module.exports = logger;

或者,您可以导出以下实例Logger

module.exports = new Logger();

这是一个最小的更改,并且会在您确实想要公开构造函数的情况下进行最小更改。

如果您确实想要创建多个Logger实例,那么您会被构造函数困住——但不用担心,这是一件好事。您也可以init用构造函数替换。

function Logger(pr) {
    this.prefix = pr;
}

Logger.prototype.log = function(message) {
    console.log("[%s] %s", this.prefix, message);
};

module.exports = Logger;

var Logger = require("./logger");
var logger = new Logger("MAIN");
于 2013-09-29T22:15:42.080 回答
2

在 JavaScript 中,function Logger() {}定义构造函数或您的对象。(顺便说一句,您不想this从构造函数返回。)

是的,您必须创建对象的实例才能访问您在对象原型中定义的函数。

要隐藏记录器类,您还可以通过执行以下操作来创建“静态”对象:

var Logger = {};
(function () {
    var logger = function (pr) {
        this.mPrefix = pr;
    };

    logger.prototype.log = function (str) {
        console.log('[' + this.mPrefix + ']' + str);
    };
    Logger.getLogger = function (pr) {
        return new logger(pr);
    };
})();

现在您必须调用Logger.getLogger()以获取新实例。

顺便说一句。阅读本文以了解 JavaScript对象

于 2013-09-29T22:16:22.017 回答