Saransh Mohapatra
Saransh Mohapatra

Reputation: 9636

Coding Style in node.js

Style 1: Objects with constructor/prototype

function DB(url) {
    this.url = url;
}

DB.prototype.info = function (callback) {
    http.get(this.url + '/info', callback);
};

Style 2: Closures

function DB(url) {
    return { info: async.apply(http.get, url + '/info') };
}

This is just an example and assume that there are more prototype methods and private methods involved.

I have read in posts One and Two that closure style is much more preferred in nodejs over the other. Please help me clarify why using this.something syntax is bad in nodejs.

You can give your opinion about which is better, but I mostly need to know about what are the advantages and disadvantages of each style when used in nodejs.

Upvotes: 1

Views: 714

Answers (7)

vastwu
vastwu

Reputation: 1

constructor can be use like that

var db = new DB();
...   
if(db instanceof DB){
    ...
}

Closures can make private variables like

function DB(url) {
    var urlParam = '&a=b';
    return { 
        info: async.apply(http.get, url + '/info' + urlParam) 
    };
}

urlParam is a private variables cannot be get or set

if you only want a static class or simple class, use Closures.

Upvotes: 0

rafaelcastrocouto
rafaelcastrocouto

Reputation: 12161

IMHO this is discussion is larger than node ... it's about javascript language.

So I suggest read this:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

and google a lil about javascript design patterns!

Upvotes: 0

Matt Pileggi
Matt Pileggi

Reputation: 7196

Closures, when done correctly, allow you to encapsulate data through the use of the scope chain that cannot be modified by any other caller.

The prototype chain does not provide any protection in that same sense. The main drawback to the use of Objects in the fashion you describe, especially in a server or library scenario, is that the "this" keyword can be modified by the caller. You have no control over that and your code will break in wildly unpredictable ways if it occurs.

var mongo = new DB('localhost');
mongo.info.call(this);  // broken

Now it may not happen as explicitly as that but if you are passing around objects or object properties as event handlers, callbacks, etc into other functions, you have no way of knowing - or protecting against - that type of usage. So the bottom line is that the 'this' keyword is not something you can bank on. While you can completely control your immediate scope with the use of closures.

In a similar vein, you also have no guarantee that your object's prototype chain has not been altered. Unless, of course, you are creating a closure over the object and returning a wrapper.

Lastly, the closure structure more closely follows the Law of Demeter since your object would, theoretically, be "reaching through" via the prototype chain. Using a closure to encapsulate other calls allows you to expose a single method which can result in calls to another service methods. This provides greater maintainability and flexibility since you now control the methods you expose directly without relying on the prototype chain. Of course, the LoD is just one way of doing things so that may or may not be important to you.

Upvotes: 1

Paul Scheltema
Paul Scheltema

Reputation: 2043

There are benefits to both styles and i think it depends on what your module/file is trying to expose. I heavily use closure style for most modules i use in my code. (like db abstraction, cache abstraction, mail etc..) and i use constructors/prototype for objects i create a lot of (like a node in a doubly-linked-list)

=== objects with attributes defined inside a closure

if you create an object (lets call it self), inside its scope add a bunch of methods that access and attach to that object (self.x) and at the end export self, everything has access only to what you added to self and cannot access the local variables inside the function where you created self

=== constructors and prototype

on the other hand if you create constructors and add methods/fields to them trough prototype every function that attaches itself to your instance has access to its internal variables and state.

==

there are some things that work easier with prototypes like EventEmitter and Streams but it not very hard to attach them to objects also.

Javascript is both an object oriented language and functional language, and missing the heavy lifting tools on both sides

like proper inheritance ever seen this.super().super().someMethod() ?? I havn't (you need it if both superclasses have the same method name)

or nomads or simple generators at the side of functional programming.

so for me it makes sense to use both, and pick the one that's most suited to your problem.

EDIT

There is one big benefit for objects which i totally forgot about. In your second example you use a flow control library (async in this case but any defered library will do), it makes your code so much cleaner, however

for your example to work the get method of http.get has to be bound to http, which in many cases it is not. so then your code will look like http.get.bind(http) if http were an object and get was defined in its scope it would always work and allows you to pass it around to other code. (like async)

Upvotes: 0

Eduardo Cuomo
Eduardo Cuomo

Reputation: 18937

I use sjsClass: https://www.npmjs.org/package/sjsclass

Code example:

Class.extend('DB', {
    'protected url': null,

    __constructor: function (url) {
        this.url = url;
    },

    info: function (callback) {
        http.get(this.url + '/info', callback);
    }
});

Upvotes: 0

alex
alex

Reputation: 12265

It's not about a style. These two functions do two completely different things.

Closure provides an access to local variables. This way you can create private variables that aren't accessible from the outside (like url in your example). But it has a performance impact since closure is created each time your object is created.

Prototype function is faster, but it is created before object, and don't know anything about an object itself.

Sometimes it even makes sense to use both of them at the same time. :)

PS: coding style is described here: https://npmjs.org/doc/coding-style.html . It doesn't explain your particular question, but I feel I have to balance those two links in previous answer with something more sensible. :)

Upvotes: 4

Kundu
Kundu

Reputation: 4054

Node follow javascript standards. So any javascript coding style is a proper coding style for node.js. But the following links may give you the abbreviation of node.js coding style.

http://nodeguide.com/style.html

http://innofied.com/javascript-coding-standards-follow/

Upvotes: 0

Related Questions