ExtJS (JavaScript) Module Design Pattern best practices

I have a question about best practices with the Module Design Pattern. The code below is an example of the way that some of our Components are written (we use ExtJs but that shouldn't matter too much). We build a lot of our components like this and I know that this doesn't match best practices exactly. Have any thoughts to clean up the code?

Ext.ns("TEAM.COMPONENT");

function Foo() {

    // Private vars
    var privateNumber=0, myButton, privateInternalObject;

    var numberField = new Ext.form.NumberField({
        label : 'A NumberField!',
        listeners : {
            'change' : function(theTextField, newVal, oldVal) {
                console.log("You changed: " + oldVal + " to: " + newVal);
            }
        }
    });

    // Some private methods
    function changeNumField(someNumber) {
        numberField.setValue(someNumber);
    }

    // Some public methods
    this.publicFunctionSetNumToSomething() {
        changeNumField(privateNumber); 
    }

    /**
     * Initializes Foo
     */
    function init() {
        // Do some init stuff with variables & components
        myButton  = new Ext.Button({
            handler : function(button, eventObject) {
                console.log("Setting " + numberField + " to zero!");
                changeNumField(0);
            },
            text : 'Set NumberField to 0'

        });

        privateInternalObject = new SomeObject();
        word = "hello world";
        privateNumber = 5; 
    }

    init();

    return this;

};

I'm wondering a few things about this and wanted to ask and get conversation going:

  1. How important is it to initialize variables when they're declared (i.e. at the top of Foo)
  2. How might I re-initialize part of this object if a client of this Module gets to a state that it's foo object needs to be set back to it's originals
  3. What sort of memory issues might this design lead to and how can I refactor to mitigate that risk?
  4. Where can I learn more? Are there any articles that address this without relying too much on the latest and greatest of EcmaScript 5 ?

Update 2012-05-24 I just wanted to add, I think this question ( Extjs: extend class via constructor or initComponent? ) is pretty relevant to the conversation, especially considering that the top voted answer is from a "former Ext JS co-founder and core developer"

Update 2012-05-31 One more addition, this question should also be linked ( Private members when extending a class using ExtJS ). Also, here is my favorite implementation to date:

/*jshint smarttabs: true */
/*global MY, Ext, jQuery */
Ext.ns("MY.NAMESPACE");

MY.NAMESPACE.Widget = (function($) {
    /**
     * NetBeans (and other IDE's) may complain that the following line has
     * no effect, this form is a useless string literal statement, so it 
     * will be ignored by browsers with implementations lower than EcmaScript 5.
     * Newer browsers, will help developers to debug bad code.
     */
    "use strict";

    // Reference to the super "class" (defined later)
    var $superclass = null;

    // Reference to this "class", i.e. "MY.NAMESPACE.Widget"
    var $this = null;

    // Internal reference to THIS object, which might be useful to private methods
    var $instance = null;

    // Private member variables
    var someCounter, someOtherObject = {
        foo: "bar",
        foo2: 11
    };

    ///////////////////////
    /* Private Functions */
    ///////////////////////
    function somePrivateFunction(newNumber) {
        someCounter = newNumber;
    }

    function getDefaultConfig() {
        var defaultConfiguration = {
            collapsible: true,
            id: 'my-namespace-widget-id',
            title: "My widget's title"
        };
        return defaultConfiguration;
    }

    //////////////////////
    /* Public Functions */
    //////////////////////
    $this = Ext.extend(Ext.Panel, {
        /**
         * This is overriding a super class' function
         */
        constructor: function(config) {
            $instance = this;
            config = $.extend(getDefaultConfig(), config || {});

            // Call the super clas' constructor 
            $superclass.constructor.call(this, config);
        },
        somePublicFunctionExposingPrivateState: function(clientsNewNumber) {
            clientsNewNumber = clientsNewNumber + 11;
            somePrivateFunction(clientsNewNumber);
        },
        /**
         * This is overriding a super class' function
         */
        collapse: function() {
            // Do something fancy
            // ...
            // Last but not least
            $superclass.collapse.call(this);
        }
    });

    $superclass = $this.superclass;
    return $this;

})(jQuery);?

Answers:

Answer

First, this isn't specifically a module design pattern as I know it, this is a general constructor pattern. The module pattern I know is a singleton, but here you could have many instances of Foo(). That being said...

Q: How important is it to initialize variables when they're declared (i.e. at the top of Foo)

Declaring them at the top is important for clarity, but initializing them isn't as important here since you're doing so in the init. If you weren't doing this, initializing them prevents you from having to do an undefined check before testing the variable later:

var x;

function baz(){
    if (typeof(x) === 'undefined') {
        // init
    } else {
        if (x > 0) { blah } else { blah blah }
    }
}

Q: How might I re-initialize part of this object if a client of this Module gets to a state that it's foo object needs to be set back to it's originals

Is there something wrong with creating a public reset method? It will have access to the private variables.

function Foo() {
    // ...

    this.reset = function () {
        privateNumber = 0;
        // etc
    };

    // ...
}

Q: What sort of memory issues might this design lead to and how can I refactor to mitigate that risk?

I don't know.

Q: Where can I learn more? Are there any articles that address this without relying too much on the latest and greatest of EcmaScript 5 ?

Here's a good read about the Javascript module (and other) pattern(s): http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.