Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Javascript Object Orientation

I've always preferred PHP/Java over Javascript because of the way in which I can structure code in an object-orientated manner, which allows me to build complex systems that are simple to understand. Whenever I have viewed examples of javascript online, it had always looked like a jumbled mess to me that would take longer to read and understand than to just rewrite from scratch. I couldn't imagine building anything very large that I would be able to maintain a few months after having been developed.

However, taking the time to study a webpage called "OOP inJS" and building the following code sample to play with, I am confident that I can start building something large, yet maintainable in JS. Please play around with the code below for yourself, or use it as a reference as I will be doing. Code that would throw errors are commented out. Uncomment them to see for yourself that they do indeed throw an error.

// This line allows me to "append" to namespaces across class files.
if (typeof myNamespace === 'undefined') { myNamespace={}; }


/*
 * Class Foo - A class to rule all classes.
 */
myNamespace.Foo = function()
{
    var privateVar = 1; // private vars are defined with "var"
    this.publicVar = 4; // public members are defined with "this"

    /**
     * Private methods are declared without "this" and cannot
     * be called outside the object. Using var ensures that we 
     * are not simply creating a function in the global scope.
     */
    var privateMethod = function () {
        alert("Foo privateMethod privateVar: " + privateVar);
        alert("Foo privateMethod publicVar: " + this.publicVar);
    }

    /**
     * An alternative way to declare a private function
     */
    function privateMethod2() {
        alert("Foo myPrivateFunc privateVar: " + privateVar);
        alert("Foo myPrivateFunc publicVar: " + this.publicVar);
    }


    /**
     * Priviledged internal methods can access private vars and
     * can be invoked by other objects.
     */
    this.priviledgedMethod = function () {
        alert("Foo priviledgedMethod privateVar: " + privateVar);
        alert("Foo priviledgedMethod publicVar: " + this.publicVar);
    }
};


// Static properties are defined like so.
myNamespace.Foo.staticProperty = 5;


/**
 * Prototype methods can only access public vars but are "lighter"
 */
myNamespace.Foo.prototype.publicMethod = function(){
    //alert("publicMethod privateVar: " + privateVar); // this will throw an error
    alert("Foo publicMethod publicVar: " + this.publicVar); // this will think this.publicVar is undefined.
};


/**
 * Static methods are declared like so (no "prototype") and only
 * have access to static variables.
 */
myNamespace.Foo.staticMethod = function(){
    //alert("staticMethod privateVar: " + privateVar); // will throw error that privateVar not defined
    //alert("staticMethod publicVar: " + this.publicVar); // will think this.publicVar is undefined.
    alert("Foo staticMethod staticProperty: " + myNamespace.Foo.staticProperty);
};


// Run the methods
var x = new myNamespace.Bar();
x.publicMethod(); // error; `private` is undefined
x.priviledgedMethod(); // error; `private` is undefined
//x.privateMethod(); // this will throw an error (cannot invoke outside)
//x.privateMethod2();
//x.staticMethod(); // error staticMethod is not a function
myNamespace.Bar.staticMethod();

References

Last updated: 2nd June 2019
First published: 16th August 2018