您好,登錄后才能下訂單哦!
原文: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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。