Search code examples
javascriptclassobjectencapsulation

Combining javascript pseudo-class objects under a single namespace


I have some classes I ported from Java to JavaScript. I would like to combine them in a library.

for example:

var myLibrary = {
    version: 1.0,
    ...more code...
};

Now a class I would like to add to this library (this was ported from Java to JavaScript!) follows:

Edit: new version below

This class works as beautifully as is, but encapsulating it is proving difficult. I would like to do something like this:

var ticker = new myLibrary.jTicker(30,10);
var otherObj = new myLibrary.object2();

The problem seems to be I can't add the prototype stuff. It's like I need to define them outside the encapsulation. Is it even possible to include them inside? I understand I could just put the prototype stuff as inner functions and use the this.that = this hack, but I would rather not.

The reason for this question is that I have broken a game into 6 or so classes in Java that I can easily port to JavaScript, (like the jTicker class) and I would like to combine them all in the same Library namespace.

Edit: Thanks to suggestion from @Jamiec, I have completed a small utility library. It contains two such pseudo-classes. It contains some cross-browser shims. I have shared it here for everyone to see the techniques used and so that everyone can benefit from it.

ccLibrary.js:

/*****************************/
/*    Crawford Computing     */
/*  JavaScript IIFE Library  */
/*****************************/
/* Author: Jonathan Crawford */
/* Created: Nov 2016         */
/*****************************/
/* Current Version: 1.1      */
/* Version 1.1: added util   */
/* Version 1.0: added ticker */
/*****************************/
/*Please credit me if you use*/
/*my code in whole or in part*/
/*****************************/
var ccLibrary = (function(){    
    /************************************************************************/
    /*                           Ticker Class                               */
    /************************************************************************/
    /* Author: Jonathan Crawford                                            */
    /* Created: Nov 2016                                                    */
    /* version 3.0 IIFE encapsulated version                                */
    /************************************************************************/
    /*construct:                                                            */
    /*var testTicker = new ccLibrary.jTicker(viewLength,spaceSize);         */
    /*add a message                                                         */
    /*testTicker.addMessage(number,message);                                */
    /*this will get increment the start index and return the ticker         */
    /*var temp = testTicker.getTicker();                                    */
    /*call that in a timed loop and stick it wherever                       */
    /*to remove/change                                                      */
    /*if(testTicker.keyExists(number);){testicker.removeMessage(number);}   */
    /*then add the updated version                                          */
    /*testTicker.addMessage(number,newMessage);                             */
    /*message numbers need not be added in order(but will display in order) */
    /*numbers may be skipped, i.e 0,1,5,6,9 is a valid key list             */
    /*testTicker.removeMessage(number);                                     */
    /************************************************************************/
    var Ticker = function(length,spaces) {
        //make space even
        if (spaces%2 != 0) { spaces += 1; }
        //set space size]
        this.spaceSize = spaces;
        //set length
        this.viewLength = length;
        //start position
        this.position = 0;
        this.key = 0;
        //all messages
        this.messages = {};
    }
    //add message
    Ticker.prototype.addMessage = function(key,msg) {
        var halfspace = "";
        var half = this.spaceSize / 2;
        for (var i = 0; i < half; i++) { halfspace += "\u00A0"; }
        var temp = halfspace + msg + halfspace;
        this.messages[key] = temp;
    }
    //remove message
    Ticker.prototype.removeMessage = function(key) {
        delete this.messages[key];
    }
    //does key exist?
    Ticker.prototype.keyExists = function(key) {
        return (key in messages);
    }
    //get string snipit
    Ticker.prototype.getTicker = function() {
        this.position += 1;
        //set pointer to next key when end of current message reached 
        var stop = false;
        for (key in this.messages) {
            if (stop) { //execute once
                this.key = key;
                stop = false; //if this does not run we can fix it
                break; //or key will match and it will excute again
            }
            else {
                // only execute when key matches and position is past end of message
                if (key == this.key && this.position > this.messages[this.key].length-1) {
                    this.position = 0;
                    stop = true; //set flag for an execution on next key
                }
            }
        }
        while(stop){ //if new key never set
            for (key in this.messages) {
                this.key = key; //we want the first key
                stop = false;
                break;
            }
        }
        var temp = this.messages[this.key].substring(this.position);
        var work = false;
        for (key in this.messages) {
            //starting at next key
            if (work) { temp += this.messages[key]; }
            //work rest of keys
            if(key == this.key){ work = true; }
        }
        //contiue if short
        for (key in this.messages) { 
            temp += this.messages[key]; 
            if (temp.length > this.viewLength) { break; }
        }
        //return exactely enough
        return temp.substring(0,this.viewLength);
    }

    /****************************************/
    /*        Javascript Utilities          */
    /****************************************/
    /* Author: Jonathan Crawford            */
    /* Created: October,  2015              */
    /****************************************/
    /* Change History:                      */
    /* Current Ver. 2.0  Nov 2015           */
    /* Version 2.0:IIFE encapsulated version*/
    /* Version 1.1: Added fixDate           */
    /*   and isIE functions.                */
    /* Version 1.0: First Version           */
    /*  Made from Textbook.                 */
    /****************************************/
    /*construct:                            */
    /*var util = new ccLibrary.Utilities(); */
    /*call members:                         */
    /*if(util.isIE()){}                     */
    /*util.$(id) is getElementById(id)      */
    /*add text to element                   */
    /*util.setText(id)                      */ 
    /*add event                             */
    /*util.addEvent(obj,type,fn)            */ 
    /*remove event                          */
    /*util.removeEvent(obj,type,fn)         */ 
    /****************************************/
    var Utilities = function(){
        if (!Date.now) { //Older Browser Fix for Timings
            Date.now = function now() {
                return new Date().getTime();
            }
        }
    }
    Utilities.prototype.isIE = function() {
        var myNav = navigator.userAgent.toLowerCase();
        return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
    }
    Utilities.prototype.$ = function(id) { //Shortcut to the element
        if (typeof id == 'string') {
            return document.getElementById(id);
        }
    }
    Utilities.prototype.setText= function(id, message) {
        if ( (typeof id == 'string') && (typeof message == 'string') ) {
            var output = this.$(id);
            if (!output) return false;
            if (output.textContent !== undefined) {
                output.textContent = message;
            } else {
                output.innerText = message;
            }
            return true;
        }
    }
    Utilities.prototype.addEvent = function(obj, type, fn) {
        if (obj && obj.addEventListener) {
            obj.addEventListener(type, fn, false);
        } else if (obj && obj.attachEvent) {
            obj.attachEvent('on' + type, fn);
        }
    }
    Utilities.prototype.removeEvent = function(obj, type, fn) {
        if (obj && obj.removeEventListener) {
            obj.removeEventListener(type, fn, false);
        } else if (obj && obj.detachEvent){
            obj.detachEvent('on' + type, fn)
        }
    }

    return{
        version:"1.1",
        Ticker:Ticker,
        Utilities:Utilities
    };
})();

Solution

  • Use an IIFE

    var myLibrary = (function(){
    
       var jTicker = function(length,spaces) {
        //make space even
        if (spaces%2 != 0) { spaces += 1; }
        //set space size]
        this.spaceSize = spaces;
        //set length
        this.viewLength = length;
        //start position
        this.position = 0;
        this.key = 0;
        //all messages
        this.messages = {};
       }
    
       // you can have all your prototype code here here
    
       return{
          version:"1.0",
          jTicker:jTicker
       };
    
    })();
    

    usage

    var myInstance = new myLibrary.jTicker(10,30);