ExtJS(JavaScript)模块设计模式最佳实践

12

我有一个关于模块设计模式最佳实践的问题。下面的代码是我们一些组件编写方式的示例(我们使用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;

};

我有一些疑问,想要询问并开展交流:

  1. 在变量声明时初始化变量(即在Foo的顶部)有多重要?
  2. 如果此模块的客户端达到需要将其foo对象设置回原始值的状态,我该如何重新初始化该对象的一部分?
  3. 这种设计可能导致哪些内存问题,我该如何重构以减少风险?
  4. 我在哪里可以了解更多信息?有没有一些文章可以解决这个问题,而不过度依赖最新的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'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);​

2
ExtJS文档指南充满了有关这个领域的极好建议。至少要查看“类系统”、“组件”和“MVC应用程序架构”指南,它们会对您有很大帮助。 - Tommi
1个回答

5

首先,这不是我所知道的特定模块设计模式,而是一般构造函数模式。我所知道的模块模式是单例模式,但在这里,你可以有许多Foo()实例。话虽如此...

Q:声明变量时初始化多么重要(例如,在Foo的顶部)

在顶部声明变量对于清晰度很重要,但在这里初始化并不那么重要,因为您在init中进行了初始化。如果您没有这样做,初始化它们可以避免在稍后测试变量之前执行未定义检查:

var x;

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

问:如果此对象的客户端达到需要将其foo对象设置回原始状态的状态,我该如何重新初始化部分对象?

创建一个公共重置方法有什么问题吗?它将访问私有变量。

function Foo() {
    // ...

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

    // ...
}

问: 这个设计可能导致什么样的内存问题,如何重构以减轻风险?

我不知道。

问: 我该在哪里学习更多?是否有关于这个问题的文章,而不要过多地依赖最新的EcmaScript 5?

这是一个关于Javascript模块(和其他)模式的好文章:http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript


我99.99%会接受你的答案 :) 我知道,回复有点慢,但我确实有一些后续想法。此外,我想为自己将来的参考链接到这里:https://dev59.com/0G855IYBdhLWcg3w1oA8 - blong
对于这个答案中描述的模式,您有什么想法吗?https://dev59.com/SHI-5IYBdhLWcg3wsKv9 - blong
1
我对ExtJS的了解不够全面,但在我看来,它似乎是一个很好的模块化实现。 - mVChr
嗨,mVChr或@Tom,你们对此有何想法?https://dev59.com/0G855IYBdhLWcg3w1oA8#KU0EoYgBc1ULPQZFX3It - blong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接