您好,登录后才能下订单哦!
原文:ExtJS - Efficient coding style guide
作者:Raja
切勿使用“new”关键字:在Ext JS中,使用“new”关键字来创建一个组件或类的实例是一种错误的做法,因为这没有遵循组件的生命周期。应该使用Ext.create方法来创建对象,例如:
[javascript] view plaincopy
错误: var obj = new Ext.panel.Panel();
正确: var obj = Ext.create(‘Ext.panel.Panel’);
初始化直接量:不要直接创建直接量的对象,例如,使用以下javascript来创建空白对象:
[javascript] view plaincopy
在javascript中,以上都是创建对象的不正确方式,这是因为如果使用这些处理方式,控制需要去遍历整个类的层次。因此,作为替代,可以使用以下方式来创建这些类的对象:
[javascript] view plaincopy
不
过,你接手的可能是别人编写的遗留代码,因而会注意到构造函数的一个“特色”(这或者是另一个不使用它的理由)。“特色”的主要问题是Object的构造
函数可接受参数,并且它会根据传入的值来决定是否将对象的创建委托给另一个内置构造函数,而最终返回的对象可能不是你所预期的,例如:
[javascript] view plaincopy
// Warning: antipatterns ahead
// an empty object
var o = new Object();
console.log(o.constructor === Object); // true
// a number object
var o = new Object(1);
console.log(o.constructor === Number); // true
var stringObj = ‘’;
var arrayObj = [];
var obj = {};
var stringObj = new String();
var arrayObj = new Array();
var obj = new Object();
更聪明的使用getCmp:
它将根据传递的id值返回匹配的对象(Ext
JS对象)。这是一种快速返回对象的方法。所有对象在创建的时候,都需要使用他们的id作为关键字注册为一个单一对象,这样,使用
Ext.getCmp(myId)就可以寻找并返回RegistrationObject["myId"],因此,这会变得非常快捷。
不过,如果都个组件使用了相同的id,它就会失效。在这种情况下,它将会返回最后一个查找到的对象。基于这点,建议尽量不要使用这个来获取对象。建议的做法是只使用该方法一次,然后将结果保存到一个变量,再在其他地方通过变量来引用对象。
如果需要为多个组件定义相同的id,建议使用itemId。通过这篇文章可了解id和itemId直接的不同。
避免不比亚的全局变量:
使用全局变量的主要问题就是它可在javascript应用程序或Web页面中共享所有代码。这可能会与使用相同名称的命名空间引起冲突,在应用程序的两
个单独部分定义具有相同名称但用途不同的全局变量的可能性是存在的。使用不必要的全局变量的第二个缺点是会造成更大的内存损耗,这是因为,对于这些全局变
量,一般情况下是不会进行垃圾回收的,因而不会释放内存。
使用var关键字来定义全局变量:使用var来定义全局变量与不使用之间的一个细微差别是:能不能使用delete操作符来删除这些变量。
使用var来定义的全局变量(包括在函数内创建的)不能使用delete来删除,例如:
[javascript] view plaincopy
// define three globals
var global_var = 1;
global_novar = 2; // antipattern
(function () {
global_fromfunc = 3; // antipattern
}());
// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true
// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"
尝试去删除那些未使用的变量和函数:不要保留代码中那些没有使用到的变量、函数或者不必要的注释,因为这些只会增加文件的大小,从而增加文件的加载时间。
避免在循环中创建对象或变量:如果没有必要,就不要在循环中创建单一的变量或对象,因为他们的数量会随着选好的迭代次数而增加,进而造成内存泄漏。
避免过度使用面板:
在大多数情况下,Ext
JS应用程序会受到面板过度使用的影响。无论什么情况都使用面板,或者更准确的说,是无论任何情况下都会使用多个面板。解决办法就是在使用一些轻量级的替
代品来代替面板。很多人都喜欢面板,不过说实在,在UI的许多部分有点过分了。我曾经看到一个用来显示几十个缩略图的UI,每个图像都是使用不同面板的
HTML内容来显示的,而这些面板是完全没必要的。可以考虑以下替代方法……
是否可以使用Ext.container.Container,而不是Ext.panel.Panel来减少开销?
是否可以使用数据视图(DataView)来渲染所有数据而不是单独的组件?
是否可以使用自定义的Ext.Component?可以使用不同的配置项来将HTML猪肉到组件:autoEl、html、tpl或数据。
是否可使用HTML和CSS,而不是完整的组件?使用Ext.Template或Ext.XTemplate可能更实际。
var arrayLength = arrayObj.lenght;
var obj = Abc.xyz.foo.bar.againFoo.againBar.finalObj;
for( var I = 0; I < arrayLenght; i++){
//pattern
If(obj === arrayObj[i]){
Alert(‘pattern code’);
}
}
var arrayLength = arrayObj.lenght;
for( var I = 0; I < arrayLenght; i++){
//anti pattern
If(Abc.xyz.foo.bar.againFoo.againBar.finalObj === arrayObj[i]){
Alert(‘Anti pattern code’);
}
}
// antipattern
myname = "global"; // global variable
function func() {
alert(myname); // "undefined"
var myname = "local";
alert(myname); // "local"
}
func();
for (var i = 0; i < myarray.length; i++) { //antipattern use of collection length
// do something with myarray
}
//Right pattern
var arrLength = myarray.length;
for (var i = 0; i < arrLength; i++) {
// do something with myarray
}
// 1.
// for-in loop
for (var i in man) {
if (man.hasOwnProperty(i)) { // filter
console.log(i, ":", man[i]);
}
}
/*
result in the console
hands : 2, legs : 2, heads : 1
*/
// 2.
// antipattern:
// for-in loop without checking hasOwnProperty()
for (var i in man) {
console.log(i, ":", man[i]);
}
/*
result in the console
hands : 2, legs : 2, heads : 1, clone: function()
*/
var man = {hands: 2, legs: 2, head: 1};
//somewhere else in the code
// a method was added to all object
If( typeof Object.prototype.clone === undefined){
Object.prototype.clone = function(){};
}
var zero = 0;
if (zero === false) {
// not executing because zero is 0, not false
}
// antipattern
if (zero == false) {
// this block is executed...
}
console.log(typeof un); // "undefined"
var jsstring = "var un = 1; console.log(un);";
eval(jsstring); // logs "1"
console.log(typeof un); // "number"
alert(parseInt("8")); // "Will print 8"
alert(parseInt("08")); // "Will print 0"
alert(parseInt("08,10")); // "Will print 8"
If we use parseInt(“08”), it gives octal value of 08.
// antipattern
// for illustration only
// global functions
function foo() {
alert('global foo');
}
function bar() {
alert('global bar');
}
function hoistMe() {
console.log(typeof foo); // "function"
console.log(typeof bar); // "undefined"
foo(); // "local foo"
bar(); // TypeError: bar is not a function
// function declaration:
// variable 'foo' and its implementation both get hoisted
function foo() {
alert('local foo');
}
// function expression:
// only variable 'bar' gets hoisted
// not the implementation
var bar = function () {
alert('local bar');
};
}
hoistMe();
// unsafe and antipattern
var MYAPP = {};
// better
if (typeof MYAPP === "undefined") {
var MYAPP = {};
}
// or shorter
var MYAPP = MYAPP || {};
var o = being.person.man.bodyparts;
o.arms = true;
o.legs = true;
being.person.man.bodyparts.arms = true;
being.person.man.bodyparts.legs= true;
with (being.person.man.bodyparts) {
arms = true;
legs = true;
}
componentObj.items.items[0] = newObject;
var anObj = componentObject.items.items[0].items.items[1];
Ext.create(‘Ext.panel.Panel’,{
height: 200,
width: 500,
//layout: ‘hbox’, // anti pattern if layout is not defined
items:[
{
xtype: ‘button’,
id: ‘button1’
flex: 1
},{
xtype: ‘button’,
id: ‘button2’
flex: 1
}
]
});
Ext.create(“Ext.panel.Panel”,{
height: Ext.getBody().getViewSize().height,
width: Ext.getBody().getViewSize().width
);
Ext.create(‘Ext.panel.Panel’,{
height: 200,
width: 500,
layout: ‘hbox’,
items:[
{
xtype: ‘button’,
id: ‘button1’
flex: 1
},{
xtype: ‘button’,
id: ‘button2’
flex: 1
}
]
});
尽量使用Ext JS的方法来访问或维护DOM,以获得跨浏览器支持,否则某些代码在某些浏览器可能会失败,这是因为每个浏览器都有它自己的DOM访问方式。
当要遍历HTML集合时,缓存集合的长度
在可能的情况下,使用API的选择器
将DOM引用指派给局部变量并使用举报变量进行操作
避免在循环中进行DOM访问
Ext.define(‘MyClass’,{
constructor: function(config){
this.store.on(‘load’, this.onStoreLoad, this);
},
onStoreLoad: function(){
………;
}
});
Ext.define(‘MyClass’,{
constructor: function(config){
this.store.on(‘load’, function(){
………..;
}, this);
}
});
container.suspendLayout = true;
doSomethingToChangeLotsOfLayoutChange();
container.suspendLayout = false;
container.doLayout();
//slow code
container.add(panel);
container.add(button);
container.add(grid);
//fast
container.add(panel, button, grid);
//using an array is also fast
container.add([panel, button, grid]);
record.beginEdit();
record.set(‘name’, ‘Tom’);
record.set(‘age’, 17);
record.set(‘member’, true);
record.endEdit();
myStore = ……{
………….,
Buffered: true, // Tell grid to use a paging scroll manager to scroll and refresh table automatically.
perPageCount: 0 // never remove pages from the prefetch buffer;
}
myStore.prefetch({
start: 0,
limit: 999999,
callback: function(){
myStore.load(0, 49);
}
});
Ext.define(‘MyClass’,{
Constructor: function(config){
//this.store.on(‘load’, this.onStoreLoad, this); // this is not good
this.store.mon(‘load’, this.onStoreLoad, this);
},
onStoreLoad: function(){
………;
}
});
Ext.data.proxy.MemoryProxy:MemoryProxy是一个辅助性的代理。通常,它用来加载一些内联数据到存储。MemoryProxy的内容会在页面刷新后对视。它通常用来加载临时数据。
Ext.data.proxy.SessionStorage:SessionStorageProxy 使用的是新的HTML5的SessionStorage API来加载和保持数据到客户端浏览器。SessionStorage设置的字段是基于窗口的,这意味着浏览器关闭后,数据也会丢失,即使网站在另一个浏 览器窗口依然是打开的。SessionStorage的数据被局限于创建他的浏览器窗口中。
Ext.data.proxy.LocalStorage:LocalStorageProxy 使用新的HTML5的localStorage来加载和保存数据到客户端浏览器。LocalStorage可在域中设置字段,这意味着关闭浏览器后再打开 它,数据还在LocalStorage中。LocalStorage允许长期存储,此外还可以在所有浏览器的标签页或窗口中访问它。
var dateString = "03/20/2008";
var dateString = "2008/03/20";
var dateString = "03-20-2008";
var dateString = "March 20, 2008";
var dateString = "Mar 20, 2008";
var dateString = "Oct 2, 2011";
作者会持续更新这篇文章。如果你有任何意见会反馈,可联系作者。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。