【问题标题】:object oriented programming in node jsnode js中的面向对象编程
【发布时间】:2013-10-05 17:00:30
【问题描述】:

我有一个基本问题如下:

我在同一个目录中有 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');

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

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

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

【问题讨论】:

    标签: javascript node.js oop logging


    【解决方案1】:

    在 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对象

    【讨论】:

    • 和exports语句会怎样?
    • module.exports = 记录器;我猜,然后调用 Logger.getLogger() 来获取实例
    • 可能用于 W3Schools 链接。 W3Schools 在这里有点臭名昭著(而且不是他们总是在那个广告上谈论的那种好方式),你可能知道也可能不知道。你能在某个地方找到更好的教程吗?
    • @minitech 当然,这只是google上的第一个链接,它有一些有意义的内容^^ 将其更改为mozilla介绍developer.mozilla.org/en-US/docs/Web/JavaScript/…
    【解决方案2】:

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

    【讨论】:

    • 创建一个“静态”类并且不能被重用。因此,每当调用 init 时,都会更改 mPrefix。我猜他想重用记录器并记录具有不同前缀的东西......
    • 正是埃拉。我的目标是在不同的模块中重用记录器。
    • @px5x2:那么您理想的语法是什么?我添加了一个实际使用构造函数来做一些有用的事情的例子(它在你的消费者代码中节省了一行),但除此之外,require 缓存,你可以做的不多。
    • @Ela“创建一个“静态”类并且不能被重用”,我不这么认为,每次我“需要”记录器时,它不会在 minitech 的第一个示例中创建新的 Logger 对象?恕我直言,将通过调用 module.exports = new Logger() 创建单独的 Logger 实例。
    • @px5x2: 不,require 缓存,这就是为什么我说你会很难做到任何其他方式。但是为什么不使用构造函数呢?这就是它的用途。
    猜你喜欢
    • 2014-06-05
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多