简体   繁体   中英

object oriented programming in node js

I have a basic question as follows:

I have 2 separate modules main.js and logger.js in the very same directory. the logger.js is simply:

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;

Now, I want to use my logger in the main module like this:

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

logger.log('foo');

But node insists that Logger has no method named init or log . I also tried require('./logger.js')() , since I'm passing a function returning self object, but it did not help. What is the best practice for defining objects in other modules and exporting them? By the way, It happens to work by doing this:

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

However it seems clumsy to me. Any explanations & suggestions?

You have a constructor; that's what prototype is for. If you want one global logger object, you need to export one global logger object:

var logger = {};

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

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

module.exports = logger;

Alternatively, you can export an instance of Logger :

module.exports = new Logger();

Which is a minimal change and will be changed minimally in case you ever do want to expose the constructor.

If you did actually want to create multiple Logger instances, you're stuck with a constructor – but no worries, it's a good thing. You can replace init with the constructor, too.

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

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

module.exports = Logger;

and

var Logger = require("./logger");
var logger = new Logger("MAIN");

In JavaScript, function Logger() {} defines the constructor or your object. (You don't want to return this from the constructor, by the way.)

And yes, you would have to create an instance of your object to access the functions you defines in the prototype of your object.

To hide a the logger class you could also create a "static" object by doing something like 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);
    };
})();

Now you would have to call Logger.getLogger() to get a new instance.

And btw. read this to learn about JavaScript objects

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM