Рекомендации по разработке шаблонов модулей ExtJS (JavaScript)

У меня есть вопрос о лучших практиках с шаблоном проектирования модулей. Приведенный ниже код является примером того, как написаны некоторые из наших Компонентов (мы используем ExtJs, но это не должно иметь большого значения). Мы строим много наших компонентов, как это, и я знаю, что это точно не соответствует лучшим практикам. Есть какие-то мысли, чтобы очистить код?

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;

};

Мне интересно об этом и хотелось спросить и начать разговор:

  • Насколько важно инициализировать переменные, когда они объявлены (т.е. в верхней части Foo)
  • Как я могу повторно инициализировать часть этого объекта, если клиент этого модуля получит состояние, в котором объект foo должен быть возвращен к нему оригиналами.
  • Какие проблемы с памятью могут повлиять на этот проект и как я могу реорганизовать этот риск?
  • Где я могу узнать больше? Существуют ли какие-либо статьи, которые касаются этого, не слишком полагаясь на последний и самый большой из EcmaScript 5?

Обновление 2012-05-24 Я просто хотел добавить, я думаю, что этот вопрос (Extjs: продлить класс через конструктор или initComponent?) очень важен для разговора, особенно учитывая, что главный голосовой ответ от "бывшего соучредителя Ext JS и основного разработчика"

Обновление 2012-05-31 Еще одно дополнение, этот вопрос также должен быть связан (Частные члены при расширении класса с помощью ExtJS). Кроме того, вот моя любимая реализация на сегодняшний день:

/*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 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);​

Ответ 1

Во-первых, это не специфический шаблон дизайна модуля, как я его знаю, это общий шаблон конструктора. Модификация модуля, которую я знаю, является одноэлементной, но здесь у вас может быть много экземпляров Foo(). Это сказано...

Q: Насколько важно инициализировать переменные, когда они объявлены (т.е. в верхней части Foo)

Объявление их сверху важно для ясности, но инициализация их здесь не так важна, так как вы делаете это в init. Если вы этого не делали, их инициализация мешает вам выполнить проверку undefined перед тестированием переменной позже:

var x;

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

Q: Как я могу повторно инициализировать часть этого объекта, если клиент этого модуля получает состояние, в котором ему нужно вернуть объект foo обратно к нему оригиналы.

Что-то не так с созданием общедоступного метода reset? Он будет иметь доступ к частным переменным.

function Foo() {
    // ...

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

    // ...
}

Q: Какие проблемы с памятью могут привести к этому дизайну и как я могу реорганизовать этот риск?

Я не знаю.

В: Где я могу узнать больше? Существуют ли какие-либо статьи, которые касаются этого, не слишком полагаясь на последний и самый большой из EcmaScript 5?

Здесь хорошо читайте о модуле (и других) шаблона Javascript: http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript