我們應該如何編寫高質(zhì)量的前端代碼
編寫高質(zhì)量代碼是每一個程序員必備的技能之一,可以有效地進行項目的維護以及項目的合作開發(fā)
01 前言
這要從很久的事情開始說起,前端最初的發(fā)展就像一團渾濁的云團,什么都往一塊寫,然后東拼西湊,最后竟然能運行。其實每個人前端人都會對頁面的混雜感到頭疼,誰不想好好優(yōu)化一下呢?但是奈何那會沒有成型的工具,更沒有現(xiàn)在高質(zhì)量的組件庫,從此解放了我們的代碼編寫,真正做到了開箱即用,它不香嗎?
從最初發(fā)展到現(xiàn)在,代碼無非就是進行了高度的解耦,讓每一個部分都負責自己的內(nèi)容,把結(jié)構、樣式與行為分離,使得代碼的職能非常清晰,看什么都舒服。所以后來很多前端都要求把自家的網(wǎng)站進行重構,畢竟誰也不想接手上一代遺留下來的產(chǎn)品,自己重新寫一套都比他們的要舒服。
02 代碼維護難點
為什么說前端的代碼難以維護呢?其實主要是出于以下的三點:
瀏覽器層面
瀏覽器是我們前端人經(jīng)常打交道的工具,其實是瀏覽器孕育了前端這個大家庭,也是我們生存的根本。假如用戶不需要看東西,不需要進行交互,或者我們就不需要存在了。不知道大家是否了解過全息投影?等到那項技術普及的時候,我們又是做著什么樣的工作呢?
雖然現(xiàn)在瀏覽器的兼容性越來越好,主流的瀏覽器一般都會兼容很多css屬性,最起碼常用的、多人使用的你是一定要支持的,像flex布局這種神仙屬性。當我們習慣于使用某一個瀏覽器(如谷歌)之后,再嘗試使用360瀏覽器,你會發(fā)現(xiàn)自己根部看不下去。就像你習慣于使用谷歌搜索,但是要你使用百度一樣的道理。
所以前端瀏覽器之間的兼容是我們必須要跨過的一道坎,即使現(xiàn)在的兼容性越來越好,但是用戶群體也有很多使用IE或者360瀏覽器的,我們也不能忽略他們的使用。可是有一句話說,兼容IE就是浪費生命,自己細品一下。
技術層面
由于每一家的公司使用的技術都不太一樣,事實上很多公司都會有自己內(nèi)部的框架,我們要使用他們內(nèi)部的框架與現(xiàn)有的技術框架結(jié)合在一起,那也是一件很頭疼的事情。即使你是一位剛跳槽進來的員工,也是要學習他們內(nèi)部的技術框架你才可以進行項目的開發(fā)。
很多公司創(chuàng)立階段的時候可能vue、react等神仙框架還沒出來,就是jQuery的天下,我們的項目底層也不是一朝一夕就能改變的,所以很多公司即使知道了新技術的出現(xiàn),也不會去使用,也是處于探索階段。假設公司需要使用一種新技術進行代碼的重構,也可能因為員工對新技術的理解還不夠深刻,寫出的代碼也會存在一定的設計漏洞。所以理解不深,就很容易寫出難以維護的代碼,給我們的團隊造成閱讀困難,最終也會變成一個難以維護的項目。
團隊合作
團隊合作才是真正的難題,不像我們自己編寫的項目,想怎么寫都行,不怕有看不懂的時候。當我們提交代碼的時候也是不用經(jīng)過其他成員的同意,直接push到master分支。這些都是我們個人開發(fā)的時候做法,到了公司層面或者項目的層面,那你就直接收拾東西吧。
大型的項目一般開發(fā)人員是比較多的,每一個人都會負責不同的模塊和不同的功能,每一個人都會有自己獨立的分支,代碼合并到主分支的時候還得經(jīng)過審核,這是一個完善、系統(tǒng)的開發(fā)流程。所以項目越復雜,團隊合作的要求就會越高。一般我們都會有一種代碼開發(fā)規(guī)則,大家都應該相互遵守,不然我們就會污染正常的代碼,導致項目難以維護。所謂團隊合作的最大困難不是技術,是人。
小結(jié):
除了我們要項目的代碼進行解耦,把結(jié)構、樣式與行為進行分離之外,我們還應該重視簡潔、可復用以及結(jié)構化的特點。當你能夠做到這些的時候,你的項目就會顯得專業(yè),代碼的可維護性以及可擴展性就會越高,開發(fā)人員添加新的功能或者模塊就會顯得比較輕松。
03 高質(zhì)量結(jié)構代碼
語義化
HTML5出來之后,添加了很多新的標簽和屬性,而語義化這個概念就出現(xiàn)在前端人的眼中。之前我們編寫結(jié)構代碼的時候一般會選擇使用div與類名/ID名的方式來命名一個模塊,所謂DIV+CSS開發(fā)模式就是這樣由來。那么這種方式可否可行呢?當然是可行的,而且別人用的很舒服,就是cv操作多了點。
當然缺點是有的,比如最主要的就是結(jié)構不清晰,無論是編寫導航還是模塊、亦或是底部,全程div。這樣結(jié)構就不清晰了,如果沒有加以類名或者ID名,根本不知道你寫的代碼是屬于哪一個模塊。而且還有一點就是對搜索引擎不友好,不能準確識別你的網(wǎng)站結(jié)構和信息。
那么如何看你的代碼是否語義化呢?很簡單,把所有的樣式都去掉,看你的頁面結(jié)構是否顯示正常,一般語義化的標簽都會有默認的樣式。如果顯示還可以,結(jié)構有序就是語義化比較好了,反之你就重新寫一下吧。
模塊化
模塊化其實就是跟在語義化之后的,如果你的語義化做的比較好,那么相應的模塊化就比較好了。我認為模塊化的重點應該關注你的標簽選擇是否合理,比如文字就使用p/span標簽,標題應該使用H1-6標簽等。不能所有的文字都是用div這個萬能的標簽元素,能用p的就不要去用div,因為p本身是針對文字的,有一定的基礎樣式。
小結(jié):
不過現(xiàn)在我們似乎不會關注這些東西了,因為有了高顏值組件庫的出現(xiàn),需要什么直接cv過來使用。但是我們注意的是,并不是說這樣你就逃避學習的理由,因為無論是多高大上的組件都是由最基本的樣式和結(jié)構組成的,學會背后的造輪子思想才是最重要的。當組件不能滿足業(yè)務上的需求的時候,就需要你進行css代碼的編寫了。
04 高質(zhì)量樣式代碼
盒子模型
一般面試或多或少都會問一下你關于css盒子模型的理解,如果沒有準備的小伙伴可能會把內(nèi)容搞混了。這里再重復一遍:
IE:元素的寬度由width+border+padding組成
標準:元素的寬度就是width,本身包括了padding+border
樣式組織
關于我們頁面的樣式如何編寫,也是我們要考慮的一個問題,我們關于樣式的編寫沒有對錯只有好壞。頁面寫出來,能夠滿足自己的期望那就是對的樣式,是否合理又是另一方面的事情了。
所以這里可以參考一下樣式的結(jié)構組織:reset.css+common.css+view.css
首先第一個是基本的樣式標準,專注于底層的樣式。這里的reset是指我們把瀏覽器默認的基本樣式都重置一下,盡量滿足所有的瀏覽器樣式看起來是一致的。還記得我們之前說過通配符*嗎?那是一個及其暴力的樣式重置,但也是很危險的一個操作符。危險是因為需要遍歷頁面所有的元素節(jié)點,給他加上樣式。這里我們就推薦使用網(wǎng)上的reset.css即可,都有很多供你選擇,假如你懶得找且項目支持npm安裝,直接npm i reset-css即可,簡單快速方便。
common.css是指一些組件相關的樣式,比如我們們?nèi)绻趘ue里面寫代碼的話就知道一個vue文件可以由三部分組成,其中一個部分就是可以讓你編寫屬于組件的樣式代碼,這里我們重用組件的時候就會顯得非常方便。關于view.css其實就是一個更高層次的編寫,屬于一個頁面的樣式文件。
選擇器使用
選擇器可對某一個節(jié)點進行樣式編寫,有同學可能會說,我能把我的節(jié)點樣式應用成功就好,還需要關心它怎么使用嗎?其實要的,我們先從css選擇器的匹配方案說起,選擇器是從右向左進行匹配的,.class ul li a p這樣的選擇器,會先從全局匹配p標簽然后再匹配a標簽,依次類推。
所以第一個問題就是我們一定要避免選擇器的嵌套過深,因為很耗費性能。假如可以使用ID匹配到唯一的元素就不用使用其他的選擇器了。也正是因為選擇器的這種匹配規(guī)則,使得元素更高效的匹配,也是經(jīng)過長期的驗證得來的結(jié)論。最后我們應該更加注意樣式的繼承,避免多次編寫重復樣式,所謂少用組合,多用繼承原則。
近年來出現(xiàn)的css預處理器可以有效地提高樣式的編寫,使用一種面向?qū)ο蟮膶懛ǎ蟪潭葘邮酱a進行復用,有stylus、scss、less等,讀者可以自行去官網(wǎng)了解。
編碼風格
樣式風格:關于css的編碼風格也是因人而異,一般來說我們應該使用多行的寫法,因為這樣可讀性就更高。假如樣式代碼寫在一行,難免造成閱讀困難的情況。后期我們進行項目發(fā)布的時候可以進行對代碼的壓縮。
id/class:id選擇器一般使用在全局唯一的元素節(jié)點上面,如果確定元素節(jié)點唯一的情況下我們就可以使用,但是假如元素節(jié)點不唯一,那么就推薦使用class。
05 高質(zhì)量的行為代碼
良好習慣
因為項目涉及到多人開發(fā),每個人自己使用的變量應該自己來維護,這樣可以有效避免代碼沖突,覆蓋正常的代碼等。所以我們應該禁止直接在全局的作用域下進行代碼的編寫,這樣很容易對別人的項目模塊造成影響。那么我們的避免的方法有哪些呢?
團隊合作避免沖突
我們把自己的代碼寫在一個匿名函數(shù)里面,如(function(){})(),這樣代碼里面的變量就不會是全局的了,而是屬于這個函數(shù)的內(nèi)部變量,不會對他人的代碼造成影響。用匿名的方式把代碼包裹起來,可以有效控制全局變量,避免沖突隱患。
統(tǒng)一入口
我們還可以給函數(shù)一個統(tǒng)一的入口加載文件,可以選擇函數(shù)入口為init,這樣所有初始化的操作都會在這里進行。通過這樣我們就可以模擬DOMReady的事件了。
CSS放在頭部,JS放在底部
這個操作應該是每個人都應該遵循的做法,這樣更有利于瀏覽器頁面的加載優(yōu)化,減少頁面空白的時間,提升用戶體驗。
JS分層
其實這里的分層和css的分層道理是一樣的,也可以參考base層、common層、以及view層的形式。其中base層可以封裝不同瀏覽器的差異,提供統(tǒng)一的接口,完成一些兼容的工作。common層提供可復用的組件,功能是給view層提供組件。common層和base層都可以為view層提供組件,不同的是common層可以提供更龐大的組件。比如一些拖拽功能的實現(xiàn)等。關于view層就是直接對前兩層的調(diào)用,這里是關于頁面邏輯的實現(xiàn)部分,如進行接口的請求等與具體功能需求相關的操作。
實用技巧
彈性
彈性是指我們能夠輕松應對客戶提出來的需求,不用每添加一個需求就修改一些js代碼,這是很不方便的事情。比如像事件代理一樣,可以實現(xiàn)一些精簡的操作,不用每添加一個節(jié)點就手動添加事件的監(jiān)聽函數(shù)。
可復用性
現(xiàn)在基本上我們實現(xiàn)什么的功能都要先考慮一下如何才可以把寫的代碼進行復用,以減少一些業(yè)務相關或功能相關的代碼,做到一次編寫,到處可用。能夠公用且不影響組件之間的功能就是我們的追求。實現(xiàn)的方法我們可以通過傳參的形式來進行。
避免副作用
我們開發(fā)的基礎代碼可能能夠滿足我們目前的需求,但也可能我們在使用的過程當中產(chǎn)生了一些副作用不是我們想要的,為了避免這個問題,我們應該考慮一下是否我們的函數(shù)耦合性太高,考慮解耦等。
06 小結(jié)
今天就和大家聊一下關于編寫高質(zhì)量的代碼的事情,其實還有很多方面來不及編寫,讀者自己也可以自行查閱相關資料。主要是從結(jié)構、樣式以及行為三個方面來進行講解,這也是對應著我們前端的基本語言html,css以及js。
結(jié)構方面我們說了語義化編寫和模塊化編寫,樣式方面我們說了盒子模型,樣式的編寫、樣式風格和選擇器的使用等,行為方面我們說了關于編寫的良好習慣,js分層等。
其實具體的實現(xiàn)還得大家自己進行感悟,這些都是前人總結(jié)下來的經(jīng)驗而已,項目之中的具體細節(jié)可以依據(jù)以上的規(guī)則來進行編寫,相信應該會提升一個代碼質(zhì)量層級。
參考書籍
編寫高質(zhì)量代碼——web前端開發(fā)修煉之道
推薦閱讀
我的公眾號能帶來什么價值?(文末有送書規(guī)則,一定要看)
每個前端工程師都應該了解的圖片知識(長文建議收藏)
為什么現(xiàn)在面試總是面試造火箭?

