Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programming OOP in Javascript - Properly

I'm interesting in improving my javascript code to be properly OOP.... currently I tend to do something like this:

jQuery(document).ready(function () {
    Page.form = (function () {
        return {
            //generate a new PDF
            generatePDF: function () {

            },
            //Update the list of PDFs available for download
            updatePDFDownloads: function () {

            },
            /*
             * Field specific functionality
             */
            field: (function () {
                return {
                    //show the edit prompt
                    edit: function (id, name) {

                    },
                    //refresh the value of a field with the latest from the database
                    refresh: function (id) {

                    }
                };
            }())
        };
    }());
});

In the end it's just mainly organized functions I suppose... what's a good resource where I can learn to program javascript in an OOP manner, or what suggestions would you have for improving my current style of programming?

It seems like I should do a sort of model prototype and have my form object inherit from that prototype.

(I'm using jQuery instead of $ because of conflicts with prototypeJS)

like image 741
Webnet Avatar asked Apr 28 '11 19:04

Webnet


1 Answers

Your question is quite broad so I don't think a complete answer is possible here. But here are a few points.

Regarding the code you have shown. You're jumping a couple of redundant hoops.

  1. Unless you're accessing the DOM in some way, there is no need to wrap your code in jQuery(document).ready()
  2. There is no need to return an object from a self calling anonymous function unless you're closing over some private functions or data

The object you have created can be created more simply (a good thing) like this

var Page = {
    form: {
        //generate a new PDF
        generatePDF: function () {

        },
        //Update the list of PDFs available for download
        updatePDFDownloads: function () {

        },
        /*
        * Field specific functionality
        */
        field: {
            //show the edit prompt
            edit: function (id, name) {

            },
            //refresh the value of a field with the latest from the database
            refresh: function (id) {

            }
        }
    }
};

It's easier to read and less confusing, only do things that buy you something. see cargo cult programming

Here's an example using a self calling anonymous function to create private members

var Obj = (function() {
    privateFunction( param ) {
        // do something with param
    }

    var privateVar = 10;

    return {
        // publicMethod has access to privateFunction and privateVar
        publicMethod: function() {
            return privateFunction( privateVar );
        }
    }

})();

The structure you have used, object literals are very good, as you say, at grouping a set of functions (methods) and properties. This is a kind of namespace. It is also a way of creating a Singleton. You may also want to create many objects of the same Class.
JavaScript doesn't have classes like traditional OO languages (I'll get to that) but at the simplest level it's very easy to create a 'template' for creating objects of a particular type. These 'templates' are normal functions called constructors.

// a constructor
// it creates a drink with a particular thirst quenchingness
function Drink( quenchingness ) {
    this.quenchingness = quenchingness;
}

// all drinks created with the Drink constructor get the chill method
// which works on their own particular quenchingness
Drink.prototype.chill = function() {
   this.quenchingness *= 2; //twice as thirst quenching
}

var orange = new Drink( 10 );
var beer   = new Drink( 125 );

var i_will_have = ( orange.quenchingness > beer.quenchingness ) 
    ? orange 
    : beer; //beer

var beer2  = new Drink( 125 );
beer2.chill();

var i_will_have = ( beer2.quenchingness > beer.quenchingness )
    ? beer2 
    : beer; //beer2 - it's been chilled!

There's a lot to know about constructors. You'll have to search around. There are lots of examples on SO.
Inheritance, the foundation of OO, is not that intuitive in js because it is prototypal. I won't go into that here because you will more than likely not use js's native prototypal inheritance paradigm directly.
This is because there are libraries that mimic classical inheritance very effectively, Prototype (inheritance) or mootools (Class) for example. There are others.

Many say that inheritance is overused in OO and that you should favour composition and this brings me to what I initially set out to recommend when I started this rambling answer.

Design patterns in JavaScript are as useful as in any OO language and you should familiarise yourself with them

I recommend you read Pro JavaScript Design Patterns. There, that's it

like image 92
meouw Avatar answered Oct 13 '22 12:10

meouw