您好,登錄后才能下訂單哦!
這篇文章主要介紹如何寫出高質(zhì)量JS代碼,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
一、如何書寫可維護(hù)性的代碼
當(dāng)出現(xiàn)bug的時(shí)候如果你能立馬修復(fù)它是最好的,此時(shí)解決問題的四路在你腦中還是很清晰的。否則,你轉(zhuǎn)移到其他任務(wù)或者bug是經(jīng)過一定的時(shí)間才出現(xiàn)的,你忘了那個(gè)特定的代碼,一段時(shí)間后再去查看這些代碼就 需要:
1.花時(shí)間學(xué)習(xí)和理解這個(gè)問題 2.化時(shí)間是了解應(yīng)該解決的問題代碼
還有個(gè)問題,特別對于大的項(xiàng)目或是公司,修復(fù)bug的這位伙計(jì)不是寫代碼的那個(gè)人(且發(fā)現(xiàn)bug和修復(fù)bug的不是同一個(gè)人)。因此,必須降低理解代 碼花費(fèi)的時(shí)間,無論是一段時(shí)間前你自己寫的代碼還是團(tuán)隊(duì)中的其他成員寫的代碼。這關(guān)系到底線(營業(yè)收入)和開發(fā)人員的幸福,因?yàn)槲覀兏鼞?yīng)該去開發(fā)新的激動(dòng) 人心的事物而不是花幾小時(shí)幾天的時(shí)間去維護(hù)遺留代碼。所以創(chuàng)建可維護(hù)性代碼是至關(guān)重要的,一般可維護(hù)性的代碼有以下幾個(gè)原則:
可讀性
一致性
可預(yù)測性
看上去就像同一個(gè)人寫的
已記錄
二、全局變量的問題
全局變量的問題在于,你的JavaScript應(yīng)用程序和web頁面上的所有代碼都共享了這些全局變量,他們住在同一個(gè)全局命名空間,所以當(dāng)程序的兩個(gè)不同部分定義同名但不同作用的全局變量的時(shí)候,命名沖突在所難免。web頁面包含不是該頁面開發(fā)者所寫的代碼也是比較常見的,例如:
第三方的JavaScript庫
廣告方的腳本代碼
第三方用戶跟蹤和分析腳本代碼
不同類型的小組件,標(biāo)志和按鈕
例如說,該第三方腳本定義了一個(gè)全局變量,叫做A;接著,在你的函數(shù)中也定義一個(gè)名為A的全局變量。其結(jié)果就是后面的變量覆蓋前面的,第三方腳本就一下子失效啦!而且很難debug出來。
因此:盡可能少的使用全局變量是很重要的,例如命名空間模式或是函數(shù)立即自動(dòng)執(zhí)行,但是要想讓全局變量少最重要的還是始終使用var來聲明變量。
三、忘記var作用的副作用
隱式全局變量和明確定義的全局變量間有些小的差異,就是通過delete操作符讓變量未定義的能力。具體如下:
通過var創(chuàng)建的全局變量(任何函數(shù)之外的程序中創(chuàng)建)是不能被刪除的。
沒有通過var創(chuàng)建的隱式全局變量(無視是否在函數(shù)中創(chuàng)建)是能被刪除的。
所以隱式全局變量并不是真正的全局變量,但它們是全局對象的屬性。屬性是可以通過delete操作符刪除的,而變量是不能的,具體代碼我就不寫了。
四、訪問全局對象
在瀏覽器中,全局對象可以通過window屬性在代碼的任何位置訪問(除非你做了些比較出格的事情,像是聲明了一個(gè)名為window的局部變量)。但是在其他環(huán)境下,這個(gè)方便的屬性可能被叫做其他什么東西(甚至在程序中不可用)。如果你需要在沒有硬編碼的window標(biāo)識(shí)符下訪問全局對象,你可以在任何層級(jí)的函數(shù)作用域中做如下操作:
var global = (function () { return this; }());
五、for循環(huán)
在for循環(huán)中,你可以循環(huán)取得數(shù)組或是數(shù)組類似對象的值,譬如arguments和HTMLCollection對象。通常的循環(huán)形式如下:
// 次佳的循環(huán) for (var i = 0; i < myarray.length; i++) { // 使用myarray[i]做點(diǎn)什么 }
這種形式的循環(huán)的不足在于每次循環(huán)的時(shí)候數(shù)組的長度都要去獲取下。這回降低你的代碼,尤其當(dāng)myarray不是數(shù)組,而是一個(gè)HTMLCollection對象的時(shí)候。
六、不擴(kuò)展內(nèi)置原型
擴(kuò)增構(gòu)造函數(shù)的prototype屬性是個(gè)很強(qiáng)大的增加功能的方法,但有時(shí)候它太強(qiáng)大了。增加內(nèi)置的構(gòu)造函數(shù)原型(如Object(), Array(), 或Function())挺誘人的,但是這嚴(yán)重降低了可維護(hù)性,因?yàn)樗屇愕拇a變得難以預(yù)測。使用你代碼的其他開發(fā)人員很可能更期望使用內(nèi)置的 JavaScript方法來持續(xù)不斷地工作,而不是你另加的方法。另外,屬性添加到原型中,可能會(huì)導(dǎo)致不使用hasOwnProperty屬性時(shí)在循環(huán)中顯示出來,這會(huì)造成混亂。
七、避免隱式類型轉(zhuǎn)換
JavaScript的變量在比較的時(shí)候會(huì)隱式類型轉(zhuǎn)換。這就是為什么一些諸如:false == 0 或 “” == 0 返回的結(jié)果是true。為避免引起混亂的隱含類型轉(zhuǎn)換,在你比較值和表達(dá)式類型的時(shí)候始終使用===和!==操作符。
var zero = 0; if (zero === false) { // 不執(zhí)行,因?yàn)閦ero為0, 而不是false } // 反面示例 if (zero == false) { // 執(zhí)行了... }
八、避免eval()
如果你現(xiàn)在的代碼中使用了eval(),記住該咒語“eval()是魔鬼”。此方法接受任意的字符串,并當(dāng)作JavaScript代碼來處理。當(dāng)有 問題的代碼是事先知道的(不是運(yùn)行時(shí)確定的),沒有理由使用eval()。如果代碼是在運(yùn)行時(shí)動(dòng)態(tài)生成,有一個(gè)更好的方式不使用eval而達(dá)到同樣的目 標(biāo)。例如,用方括號(hào)表示法來訪問動(dòng)態(tài)屬性會(huì)更好更簡單:
// 反面示例 var property = "name"; alert(eval("obj." + property)); // 更好的 var property = "name"; alert(obj[property]);
使用eval()也帶來了安全隱患,因?yàn)楸粓?zhí)行的代碼(例如從網(wǎng)絡(luò)來)可能已被篡改。這是個(gè)很常見的反面教材,當(dāng)處理Ajax請求得到的JSON 相應(yīng)的時(shí)候。在這些情況下,最好使用JavaScript內(nèi)置方法來解析JSON相應(yīng),以確保安全和有效。若瀏覽器不支持JSON.parse(),你可 以使用來自JSON.org的庫。
同樣重要的是要記住,給setInterval(), setTimeout()和Function()構(gòu)造函數(shù)傳遞字符串,大部分情況下,與使用eval()是類似的,因此要避免。在幕后,JavaScript仍需要評(píng)估和執(zhí)行你給程序傳遞的字符串:
// 反面示例 setTimeout("myFunc()", 1000); setTimeout("myFunc(1, 2, 3)", 1000); // 更好的 setTimeout(myFunc, 1000); setTimeout(function () { myFunc(1, 2, 3); }, 1000);
使用新的Function()構(gòu)造就類似于eval(),應(yīng)小心接近。這可能是一個(gè)強(qiáng)大的構(gòu)造,但往往被誤用。如果你絕對必須使用eval(),你 可以考慮使用new Function()代替。有一個(gè)小的潛在好處,因?yàn)樵谛翭unction()中作代碼評(píng)估是在局部函數(shù)作用域中運(yùn)行,所以代碼中任何被評(píng)估的通過var 定義的變量都不會(huì)自動(dòng)變成全局變量。另一種方法來阻止自動(dòng)全局變量是封裝eval()調(diào)用到一個(gè)即時(shí)函數(shù)中。
考慮下面這個(gè)例子,這里僅un作為全局變量污染了命名空間。
console.log(typeof un); // "undefined" console.log(typeof deux); // "undefined" console.log(typeof trois); // "undefined" var jsstring = "var un = 1; console.log(un);"; eval(jsstring); // logs "1" jsstring = "var deux = 2; console.log(deux);"; new Function(jsstring)(); // logs "2" jsstring = "var trois = 3; console.log(trois);"; (function () { eval(jsstring); }()); // logs "3" console.log(typeof un); // number console.log(typeof deux); // "undefined" console.log(typeof trois); // "undefined"
另一間eval()和Function構(gòu)造不同的是eval()可以干擾作用域鏈,而Function()更安分守己些。不管你在哪里執(zhí)行 Function(),它只看到全局作用域。所以其能很好的避免本地變量污染。在下面這個(gè)例子中,eval()可以訪問和修改它外部作用域中的變量,這是 Function做不來的(注意到使用Function和new Function是相同的)。
(function () { var local = 1; eval("local = 3; console.log(local)"); // logs "3" console.log(local); // logs "3" }()); (function () { var local = 1; Function("console.log(typeof local);")(); // logs undefined
九、編碼規(guī)范
建立和遵循編碼規(guī)范是很重要的,這讓你的代碼保持一致性,可預(yù)測,更易于閱讀和理解。一個(gè)新的開發(fā)者加入這個(gè)團(tuán)隊(duì)可以通讀規(guī)范,理解其它團(tuán)隊(duì)成員書寫的代碼,更快上手干活。
十、縮進(jìn)
代碼沒有縮進(jìn)基本上就不能讀了。唯一糟糕的事情就是不一致的縮進(jìn),因?yàn)樗瓷先ハ袷亲裱艘?guī)范,但是可能一路上伴隨著混亂和驚奇。重要的是規(guī)范地使用縮進(jìn)。
十一、注釋
你必須注釋你的代碼,即使不會(huì)有其他人向你一樣接觸它。通常,當(dāng)你深入研究一個(gè)問題,你會(huì)很清楚的知道這個(gè)代碼是干嘛用的,但是,當(dāng)你一周之后再回來看的時(shí)候,想必也要耗掉不少腦細(xì)胞去搞明白到底怎么工作的。
很顯然,注釋不能走極端:每個(gè)單獨(dú)變量或是單獨(dú)一行。但是,你通常應(yīng)該記錄所有的函數(shù),它們的參數(shù)和返回值,或是任何不尋常的技術(shù)和方法。要想到注 釋可以給你代碼未來的閱讀者以諸多提示;閱讀者需要的是(不要讀太多的東西)僅注釋和函數(shù)屬性名來理解你的代碼。例如,當(dāng)你有五六行程序執(zhí)行特定的任務(wù), 如果你提供了一行代碼目的以及為什么在這里的描述的話,閱讀者就可以直接跳過這段細(xì)節(jié)。沒有硬性規(guī)定注釋代碼比,代碼的某些部分(如正則表達(dá)式)可能注釋 要比代碼多。
十二、花括號(hào){}
花括號(hào)(亦稱大括號(hào),下同)應(yīng)總被使用,即使在它們?yōu)榭蛇x的時(shí)候。技術(shù)上將,在in或是for中如果語句僅一條,花括號(hào)是不需要的,但是你還是應(yīng)該總是使用它們,這會(huì)讓代碼更有持續(xù)性和易于更新。
以上是“如何寫出高質(zhì)量JS代碼”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。