Andy
Andy

Reputation: 871

What is the common way to instantiate objects in Node.js?

The following node snippiest are from the Node.js tests and I would like to know why one way to instantiate an object is preferred over the other?

// 1
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('test', doSomething);

// 2
var net = require('net');
var server = net.createServer();
server.on('connection', doSomething);

// 3
var net = require('http');
var server = http.Server(function(req, res) {
  req.on('end', function() { ... });
});

And I'm working on a Node.js module and trying to find the common way these kind of APIs.

Upvotes: 2

Views: 1545

Answers (2)

Sean Vieira
Sean Vieira

Reputation: 159945

#1 is using JavaScript's new keyword to handle creating a new object which most likely has a prototype while #2 and #3 are using a factory method to create some object (which may or may not have a prototype).

// 1
function EventEmitter() {
    /* Disadvantage: Call this without `new` and the global variables 
    `on` and `_private` are created - probably not what you want. */
    this.on = function() { /* TODO: implement */ };
    this._private = 0;
}
/* Advantage: Any object created with `new EventEmitter`
   will be able to be `shared` */
EventEmitter.prototype.shared = function() {
    console.log("I am shared between all EventEmitter instances");
};

// 2 & 3
var net = {
    /* Advantage: Calling this with or without `new` will do the same thing
       (Create a new object and return it */
    createServer: function() {
        return {on: function() { /* TODO: implement */ }};
    }
};
/* Disadvantage: No shared prototype by default */

Upvotes: 2

Andrey Sidorov
Andrey Sidorov

Reputation: 25456

#1 and #3 are the same, http.Server can be used as a factory because of this first line in it:

if (!(this instanceof Server)) return new Server(requestListener);

#2 is useful in top-level api functions as it makes chaining simpler:

require('http').createServer(handler).listen(8080);

instead of

(new require('http').Server(handler)).listen(8080);

it's common for core api modules to expose both constructor and factory helper, like Server and createServer, and allow constructor to be used without new.

Upvotes: 2

Related Questions