节点js中的面向对象编程

时间:2013-09-29 22:13:30

标签: javascript node.js oop logging

我有一个基本问题如下:

我在同一目录中有两个独立的模块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');

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

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

然而,这对我来说似乎很笨拙。任何解释&建议?

2 个答案:

答案 0 :(得分:14)

你有一个构造函数;这就是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");

答案 1 :(得分: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()以获取新实例。

顺便说一下。将此内容读取到learn about JavaScript个对象