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

This blog is created by Stuart Page

I'm a freelance web developer and technology consultant based in Surrey, UK, with over 10 years experience in web development, DevOps, Linux Administration, and IT solutions.

Need support with your infrastructure or web services?

Get in touch