ExtJS(JavaScript)模块设计模式最佳实践 [英] ExtJS (JavaScript) Module Design Pattern best practices

查看:109
本文介绍了ExtJS(JavaScript)模块设计模式最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有关模块设计模式的最佳实践的问题。下面的代码是我们的一些组件编写方式的一个例子(我们使用ExtJs,但这不应该太重要)。我们构建了很多我们这样的组件,我知道这不完全符合最佳实践。有什么想法来清理代码?

  Ext.ns(TEAM.COMPONENT); 

函数Foo(){

//私有变量
var privateNumber = 0,myButton,privateInternalObject;

var numberField = new Ext.form.NumberField({
label:'A NumberField!',
listeners:{
'change':function(theTextField, newVal,oldVal){
console.log(你更改:+ oldVal +到:+ newVal);
}
}
});

//某些私有方法
函数changeNumField(someNumber){
numberField.setValue(someNumber);
}

//某些公共方法
this.publicFunctionSetNumToSomething(){
changeNumField(privateNumber);
}

/ **
*初始化Foo
* /
函数init(){
//对变量进行一些初始化&安培;组件
myButton = new Ext.Button({
handler:function(button,eventObject){
console.log(Setting+ numberField +to zero!);
changeNumField(0);
},
文本:'将NumberField设置为0'

});

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

init();

返回此;

};

我想知道一些关于这一点的事情,想要问和谈话:


  1. 声明初始化变量的重要性(即在Foo的顶部)

  2. 如果本模块的客户端处于 foo 对象需要重新设置为原始文件
  3. $的状态,我该如何重新初始化该对象的一部分b $ b
  4. 这种设计可能导致什么样的内存问题,如何重构以减轻风险?

  5. 在哪里可以了解更多?有没有任何文章解决这个问题,而不依赖于最新和最伟大的EcmaScript 5?

更新2012-05-24
我只是想添加,我认为这个问题( Extjs:扩展类通过构造函数或initComponent?)与会话非常相关,特别是考虑到最初的投票答案来自前Ext JS联合创始人和核心开发人员



更新2012-05-31
再一个补充,这个问题也应该链接(使用ExtJS扩展课程时的私人会员)。此外,这是迄今为止我最喜欢的实现:

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

MY.NAMESPACE.Widget =(function($){
/ **
* NetBeans(和其他IDE)可能抱怨以下行有
*没有效果,这种形式是一个无用的字符串文字语句,所以它的
*将被实现低于EcmaScript 5的浏览器忽略。
*较新的浏览器将帮助开发人员调试坏代码
* /
use strict;

//引用超级class(稍后定义)
var $ superclass = null;

//引用这个类,即MY.NAMESPACE.Widget
var $ this = null;

//内部引用此对象,这可能对私有有用方法
var $ instance = null;

//私有成员变量
var someCounter,someOtherObject = {
foo:bar,
foo2: 11
};

////////////////////
/ *私人功能* /
/////////////////////
func somePrivateFunction(newNumber){
someCounter = newNumber;
}

函数getDefaultConfig(){
var defaultConfiguration = {
collapsible:true,
id:'my-namespace-widget-id'
标题:我的小部件的标题
};
return defaultConfiguration;
}

//////////////////
/ *公共职能* /
/ ///////////////////
$ this = Ext.extend(Ext.Panel,{
/ **
* This正在覆盖一个超级类'
* /
构造函数:function(config){
$ instance = this;
config = $ .extend(getDefaultConfig(),config || {});

//调用超级clas的构造函数
$ superclass.constructor.call(this,config);
},
somePublicFunctionExposingPrivateState:function clientsNewNumber){
clientsNewNumber = clientsNewNumber + 11;
somePrivateFunction(clientsNewNumber);
},
/ **
*这是覆盖一个超级类'function
* /
collapse:function(){
// do something fancy
// ...
//最后但并非最不重要的
$ superclass.collapse.call(本);
}
});

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

})(jQuery);


解决方案>

首先,这不是我所知道的模块设计模式,这是一个一般的构造函数模式。我知道的模块模式是一个单例,但是在这里你可以有很多Foo()的实例。这就是说...



问:在宣告变量时(如Foo的顶部)初始化变量有多重要



为了清楚起见,声明它们很重要,但是由于您在init中这样做,因此初始化它们并不重要。如果没有这样做,初始化它们将阻止您在稍后测试变量之前进行未定义的检查:

  var X; 

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



问:如果本模块的客户端处于将foo对象需要重新设置为原始文件的状态,那么我如何重新初始化这个对象的一部分

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

 函数Foo(){
// ...

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

// ...
}

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



我不知道。



问:我在哪里可以了解更多?有没有任何文章解决这个问题,而不依赖于最新和最伟大的EcmaScript 5?



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


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

解决方案

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

这篇关于ExtJS(JavaScript)模块设计模式最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆