二灯帮、編程實(shí)踐
1每强、UI松耦合
第一秉沼、將css從javascript中抽離(要改變dom樣式數(shù)據(jù),應(yīng)該去操作dom的class名而非dom的style屬性辕狰,后續(xù)要修改此樣式只需到對(duì)應(yīng)的css文件中修改而不用修改js文件)改备;
第二、將javascript從HTML中抽離蔓倍,比如下面的寫法是不好的
<!-- 不好的寫法 -->
<input type="button" onclick="doSomething" />
js應(yīng)該放在外部文件中悬钳,方便維護(hù);
第三偶翅、避免使用css表達(dá)式默勾,嚴(yán)重影響頁面性能;
第四聚谁、將HTML從javascript中抽離母剥,比如你要?jiǎng)討B(tài)生成一個(gè)N行4列的表格,表頭和tbody可以寫死在頁面里,表體你可能會(huì)這樣循環(huán)生成
// 不好的寫法
var str=""; for (var i = 0; i < data.length; i++) {
str+="<tr><td>"+ data[i].字段一 +"</td><td>"+ data[i].字段二 +
"</td><td>"+ data[i].字段三 +"</td><td>"+ data[i].字段四 +"</td></tr>";
};
$("tbody").html(str);
假如現(xiàn)在要增加一個(gè)字段媳搪,將表格的列數(shù)增加到5列铭段,你要先到html頁面修改表頭骤宣,又要到j(luò)s里修改js文件……所以秦爆,盡量將html從js中分離出去是好的做法,可以在html里面寫一個(gè)模板憔披,通過js獲取模板內(nèi)容替換變量生成html填充到tbody里面等限。
2、避免使用全局變量
命名本身就是一件比較困難的事芬膝,如果大量使用全局變量望门,隨著代碼量不斷增加,命名沖突概率隨之增高锰霜,程序維護(hù)成本也隨著增高筹误。
3、事件處理
規(guī)則1:隔離應(yīng)用邏輯
什么意思呢癣缅?好比電腦要關(guān)機(jī)厨剪,有個(gè)關(guān)機(jī)的程序放在那里,你可以按關(guān)機(jī)按鈕觸發(fā)關(guān)機(jī)程序友存,也可以點(diǎn)開始菜單再選擇關(guān)機(jī)去觸發(fā)關(guān)機(jī)程序祷膳,這個(gè)關(guān)機(jī)程序是獨(dú)立出來的。代碼也是如此屡立,當(dāng)點(diǎn)擊按鈕A或按鈕B要做的操作是一樣的時(shí)候直晨,應(yīng)該將操作獨(dú)立寫成一個(gè)函數(shù),這就是應(yīng)用邏輯隔離膨俐。
規(guī)則2:不要分發(fā)事件對(duì)象
先看一段代碼
function handleClick(event){ var popup = document.getElementById("popup");
popup.style.left = event.clientX + "px";
popup.style.top= event.clientY + "px";
popup.className = "reveal";
}
document.getElementById("demo").onclick=function(event){
handleClick(event);
};
上面這段代碼中勇皇,event被無節(jié)制地分發(fā),它從事件處理函數(shù)中傳入handClick()焚刺,event對(duì)象上包含很多信息敛摘,而handClick函數(shù)內(nèi)只用到了其中2個(gè)而已,該函數(shù)并沒有標(biāo)明哪些數(shù)據(jù)是必要的檩坚,假如此時(shí)你也要調(diào)用這個(gè)方法着撩,你必須創(chuàng)建一個(gè)evnet對(duì)象并將它作為參數(shù)傳入,而你依然不知道這個(gè)方法使用了哪些信息匾委,我們可以做如下修改
function handleClick(x,y){ var popup = document.getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "reveal";
}
document.getElementById("demo").onclick=function(event){
handleClick(event.clientX,event.clientY);
};
4拖叙、避免“空比較”
有時(shí)候我們需要檢測(cè)函數(shù)的某個(gè)參數(shù)是否存在,可能會(huì)通過判斷這個(gè)參數(shù)是否等于null來判斷出參數(shù)是否存在
var comtroller = {
process:function(items){ if(items!==null){ // 不好的寫法
items.sort(); // 執(zhí)行一些邏輯
}
}
}
這段代碼中赂乐,process方法顯然希望items是一個(gè)數(shù)組薯鳍,然后當(dāng)items的值為1時(shí),不等于null,依然進(jìn)入if語句內(nèi)了挖滤,執(zhí)行到items.sort()就報(bào)錯(cuò)了
5崩溪、檢測(cè)原始值(string、number斩松、boolean伶唯、undefined、null)惧盹,typeof就夠了
6乳幸、檢測(cè)引用值(Object、Array钧椰、Date粹断、Error),引用值也稱做對(duì)象嫡霞,一般情況下使用instanceof來檢測(cè)這個(gè)對(duì)象的構(gòu)造器是否為對(duì)應(yīng)的值即可瓶埋,當(dāng)跨域檢測(cè)時(shí),用instanceof檢測(cè)數(shù)組將失敗诊沪,解決方案是將該對(duì)象的原型調(diào)用toString()方法养筒,判斷返回的字符串是否等于[object Array]來得出結(jié)論:
// 判斷value是否為數(shù)組
function isArray(value){
return Object.prototype.toString.call(value)==="[object Array]";
}
7、檢測(cè)函數(shù) 用typeof即可娄徊,可以跨幀使用闽颇,返回"function",在IE8和更早版本的IE中寄锐,使用typeof檢測(cè)DOM節(jié)點(diǎn)中的函數(shù)(如getElementById())都返回“Objeac”而不是“function”
8兵多、檢測(cè)屬性
[](javascript:void(0); "復(fù)制代碼")
// 不好的寫法
if(object[propertyName]){ // 存在屬性propertyName
} // 不好的寫法
if(object[propertyName]!= null){ // 存在屬性propertyName
} // 不好的寫法
if(object[propertyName]橄仆!= undefined){ // 存在屬性propertyName
}
上面這段代碼中剩膘,假如屬性值為假值(false、0盆顾、null怠褐、undefined)時(shí)會(huì)出錯(cuò),判斷屬性是否存在的最好方法是使用in運(yùn)算符您宪,in運(yùn)算符僅僅會(huì)簡(jiǎn)單地判斷屬性是否存在奈懒,而不會(huì)去讀取屬性的值。
var object = {
count: 0 } // 好的寫法
if( "count" in object ){ // 這里的代碼會(huì)執(zhí)行
} // 不好的寫法
if( object["count"] ){ // 這里的代碼不會(huì)執(zhí)行
}
9宪巨、將配置數(shù)據(jù)從代碼中分離出來
什么是配置數(shù)據(jù)磷杏?比如頁面中做某個(gè)操作失敗,需要一個(gè)提示語捏卓,而不同的操作有不同的提示語极祸,此時(shí)整個(gè)提示語就是配置數(shù)據(jù)。應(yīng)該將配置數(shù)據(jù)分離出來以參數(shù)的形式傳進(jìn)去。
10遥金、拋出自定義錯(cuò)誤 throw new Error("錯(cuò)誤提示")
在代碼執(zhí)行過程中出錯(cuò)時(shí)浴捆,如果沒有任何提示或是提示比較稀少、隱晦稿械,調(diào)試是非常困難的选泻,而拋出自定義錯(cuò)誤,就是在有可能出錯(cuò)的地方溜哮,加上捕獲錯(cuò)誤的代碼拋出錯(cuò)誤滔金,將非常有利于調(diào)試色解。拋出自己的錯(cuò)誤可以使用確切的文本供瀏覽器顯示茂嗓,可以包括出錯(cuò)的行數(shù)、函數(shù)以及失敗原因科阎,有利于快速定位錯(cuò)誤原因述吸。
ECMA-262規(guī)范指出了7種錯(cuò)誤類型
1)Error : 所有錯(cuò)誤的基本類型
2)EvalError : 通過eval()函數(shù)執(zhí)行代碼出錯(cuò)時(shí)拋出
3)RangeError : 一個(gè)數(shù)字超出了它的邊界時(shí)拋出,比如試圖創(chuàng)建一個(gè)長度為-20的數(shù)組(new Array(-20))锣笨。
4)ReferenceError: 期望的對(duì)象不存在時(shí)拋出蝌矛,比如試圖在一個(gè)null對(duì)象引用上調(diào)用一個(gè)函數(shù)
5)SyntaxError: 語法錯(cuò)誤
6)TypeError: 變量不是期望的類型時(shí)拋出錯(cuò)誤
7)URIError: 給encodeURI()、encodeURIComponent()错英、decodeURI()入撒、decodeURIComponent()等函數(shù)傳遞格式非法的URI字符串時(shí)拋出
這7種錯(cuò)誤類型需要熟記。
11椭岩、不是你的對(duì)象不要?jiǎng)?/p>
開發(fā)過程中茅逮,可能會(huì)引用一些javascript類庫,你個(gè)人不是這些類庫的作者判哥,應(yīng)該遵守3條基本原則
1)不覆蓋方法
2)不新增方法
3)不刪除方法
12献雅、瀏覽器嗅探
避免瀏覽器推斷
現(xiàn)在有一種比較流行的判斷IE瀏覽器的方法是
if( document.all ){ // IE瀏覽器
}
這就屬于瀏覽器推斷,這個(gè)推斷斷定document.all只存在于IE瀏覽器塌计,而實(shí)際上Opera的一些版本也支持document.all
做特性檢測(cè)
我們知道IE9及以下的IE瀏覽器不支持placeholder屬性挺身,當(dāng)我們要給IE9及以下瀏覽器模擬placeholder效果時(shí),需要先做特性檢測(cè)锌仅,如果瀏覽器不支持placeholder屬性才用js去模擬
if( !("placeholder" in document.createElement("input")) ){
// 不支持placeholder章钾,需要模擬
}
第二部分完。
本文為轉(zhuǎn)載文章热芹。
原創(chuàng)作者:王美建