Home > Javascript > How to Create Javascript Objects

How to Create Javascript Objects

August 21st, 2009

It is easy to create Javascript objects, but this method goes one step further by allowing you to create a Javascript object with private and public methods, as well as private variables. It’s a perfect way to create a single access point for Javascript and Flash to communicate.

The project I’m currently working on requires heavy interaction between a Flash object and the HTML/DOM. Links on the page need to call methods on the Flash object, and events in the Flash object need to trigger actions on the page.

I decided to create a DOM/Flash Connector in Javascript that would expose all of the methods that each can call into the other. I wanted it to be fully encapsulated, and as object oriented as possible.

One example of what it needed to do was show extended content (in HTML) that the Flash object was not large enough to display. For example, when a photo is displayed within the Flash object, the photo’s title, description, comments, tags, rating, etc. is displayed in HTML below the Flash object.

Here is the method I chose to use:


var Connector = function(){

    var _flashElSelector = false;
    var _flashIsReady    = false;
    var _flash           = null;

    // load html into extended content area
    // this is a "private" method in the Connector class
    // it can only be called from within the returned object
    var _populateExtendedContent = function(url, data){
        $('#extendedcontent').load(url, data);
    };

    return {

        // initialize connector object
        // set the jQuery selector to be used for retrieving 
        // the Flash object element
        init : function(selector){
            _flashElSelector  = selector;
        },

        // flash is ready
        // flash calls this method as soon as it is ready to accept
        // incoming method calls
        flashReady : function(){
            // find flash object in DOM
            _flash        = $(_flashElSelector).get(0);
            _flashIsReady = true;
        },

        // show content for specified ID in extended content area
        showExtendedContent : function(id){
            // call the "private" method to display content in the
            // HTML part of the site
            _populateExtendedContent('/show/extendedcontent', {id : id} );
        },

        /**
         * Flash Methods
         */

        // show content for specified ID in Flash object
        showContent : function(id){

            // if flash isn't ready to accept method calls, ignore
            // this request
            if(_flashIsReady){

                // call the showContent() method on the Flash object
                // this is a method that is exposed by Flash that will
                // display content, based on the content's ID
                _flash.showContent(id);

                // call the showExtendedContent() method on the Connector
                // in this case, "this" refers to the same object as the
                // global "Connector" does
                // displays the extended content in the HTML area of the site
                this.showExtendedContent(id);

            }
        }

    }

// closure
}();

// set the jQuery selector for retrieving the Flash object
// this is done on the individual pages that have Flash to allow
// for different IDs for the Flash objects on each page
Connector.init('#flashobject');

If the user selected some content to be displayed within the Flash object, Flash would call to the connector as follows to display the extended information for the content in HTML.

Connector.showExtendedContent(5);

If the user selected some content to be displayed within the HTML part of the site, Javascript would call to the connector as follows to display the content in Flash and the extended information for the content in HTML.

Connector.showContent(5);

Note that since the function being assigned to Connector has the (); at the end of it (line 67), it gets executed immediately. This function then returns an object that contains several functions and is assigned to the Connector variable. All of the variables and functions within Connector, that are not returned, are private and inaccessible from the global scope, but fully accessible from within the Connector, as evidenced by line 36.

If you have any questions regarding the script please feel free to post them here in the comments. I’m sure there are many other ways of creating Javascript objects, so please share your thoughts.

Be Sociable, Share!
  1. August 22nd, 2009 at 08:47 | #1

    Thanks for posting this. I think this sums up the best way to create object oriented javascript with ability for private methods and properties.

    I have been trying out RightJS (rightjs.org), which uses a Class object whereby you can create classes and extend those to other classes, and it also has the ability to encapsulate an Options class which provides a uniform way to pass options to your objects. I kind of like this way a little better because it is a little simpler.

    The line number you reference are off by one.

    Also, in line 38, could you use this.populateExtendedContent() (add the keyword “this”)? Do you have a preference on using “this” to indicate that it is a method of this object? And what about prefixing the private methods with an underscore? That might reduce maintenance headaches later on to help keep it straight which are public and private methods.

  2. Konr Ness
    August 22nd, 2009 at 11:16 | #2

    @Jansen Price
    I fixed the line numbers. Thanks.

    Regarding adding this to the populateExtendedContent() call, this will not work. I think this is where this method of creating objects differs from normal OO programming, since this refers to the object that is being returned by the function. The private methods and variables are outside of the scope of this when in the Connector.

    I do like your idea of following common programming standards and prefixing the private variables and methods with underscores. I have updated the code to do this.

  3. August 23rd, 2009 at 00:05 | #3

    I’ve started using this style in my code as well. One stylistic choice I’ve found very useful when assigning a variable that’s the result of an anonymous function like ‘Connection’ is above is to wrap the function in parentheses.

    //You have to scroll down to the bottom of the function definition
    //before being able to tell if Connector is the function or its result
    var Connector = function() {

    }();

    //Here the parens make it more obvious that it’s not just a simple
    //assignment of a function
    var Connector = (function() {

    })();

    It’s identical in meaning, but the parens convey pretty clearly that something is going on. I’ve seen this style a few places and it seems as though this is becoming the suggested coding style.

  4. August 23rd, 2009 at 15:02 | #4

    This is the Module Pattern, if anyone is interested, check out the following link for more info: http://yuiblog.com/blog/2007/06/12/module-pattern/

  5. Konr Ness
    August 24th, 2009 at 10:04 | #5

    Thanks for all the comments here. There was a lively discussion on this method on reddit.com over the weekend. Check it out here: http://www.reddit.com/r/javascript/comments/9d0qb/how_to_create_javascript_objects_this_method/

  6. nathan
    June 26th, 2012 at 22:35 | #6

    A good example of programming “into” a language instead of programming “in it” :)

    If private methods don’t exist in the language, invent them.

  1. January 28th, 2012 at 01:46 | #1