前言
這兩週參加公司的新項目,採用封閉式開發
(項目成員在會議室裏開發),晚上加班到很晚,因此沒時間和精力寫原創博客了,今天就分享下這篇《編寫高質量代碼--Web前端開發修煉之道》讀書筆記吧。
正文
欲精一行,必先通十行。
在前端開發這個領域,一專多能更是很是必要的。
table佈局缺點:
- 代碼量大,結構混亂;
- 標籤語義不明確,對搜索引擎不友好。
css佈局:div+css,或者(x)html+css。
代碼量少、結構精簡、語義清新。
代碼量少,瀏覽器端下載時間就會更短;
語義清晰就會對搜索引擎更友好。
先肯定html,肯定語義的標籤,再來選用合適的CSS。
瀏覽器會根據標籤的語義給定一個默認定樣式。
判斷網頁標籤語義是否良好的一個簡單方法就是:去掉樣式,看網頁結構是否組織良好有序,是否仍然有很好的可讀性。
測試下DevTool中有沒有禁用網頁中的CSS設置?測試下w3c官網去掉樣式後的效果。
<h>標籤,搜索引擎對其比較敏感,尤爲是h1和h2。
當頁面內標籤沒法知足設計須要時,纔會適當添加div和span等無語義標籤來輔助實現。
table佈局適合展現二維數據。
語義化標籤應注意的一些其餘問題:
- 儘量少地使用無語義標籤div和span。
- 在語義不明顯,既能夠用p也能夠用div的地方,儘可能用p,由於p默認狀況下有上下間距,去樣式後的可讀性更好,對兼容特殊終端有利。
- 不是用純樣式標籤,例如b、font和u等,改用css設置。語義上須要強調的文本能夠包含在strong或em標籤裏。
對於文件過於分散和集中的問題並無完美的解決方案,咱們須要根據實際狀況作些適當的折中。
css rest:
- 不推薦 * { margin:0; padding: 0 },推薦顯示羅列出來。也不建議寫成:{margin:0; padding:0; color:#000; font-size:12px;},由於這樣會破壞css的繼承性。
- .fl { float: left; display: inline } 其中display: inline是爲了解決IE6的雙外邊距Bug。
- .zoom { zoom: 1 } 是IE的專有屬性,爲了觸發IE的hasLayout。當zoom無效時,能夠設置「position: relative」來觸發hasLayout。
補充:
拆分模塊:
- 模塊與模塊之間儘可能不要包含相同的部分,若是有相同的部分,應將它們提取出來,拆分紅一個獨立的模塊。
- 模塊應在保證數量儘量少的原則下,作到儘量簡單,以提升重用性。
駝峯法用於區別單詞,劃線用於代表從屬關係。例如:.timeList-lastItem。
學習這種風格的命名:
.fr { float: right; }
.w25 { width: 25%; }
多用組合,少用繼承。
當樣式設置有衝突時,會採用權重高的樣式。
html標籤的權重:1,class的權重:10,ID的權重:100.
當權重相同時,會採用最近定義原則。
爲了保證樣式容易被覆蓋,提升可爲維護性,css選擇符的權重儘量低。
css的hack方式一般是 選擇符前綴法 和 樣式屬性前綴法。
<a>標籤的四種狀態定義順序,l( link )ov( visited )e h( hover )a( acitive )te,即love hate原則。
塊級元素和行內元素:
- 塊級元素能夠設置width、height屬性,行內元素設置width、height屬性無效。
- 塊級元素能夠設置margin和padding屬性。行內元素設置margin和padding的水平方向,即-left和-right有效,垂直方向的-top和-bottom無效。
- 經過修改display屬性來切換塊級元素和行內元素。
hasLayout:
是IE瀏覽器爲解析盒模型而設計的一個專有屬性,它的設計初衷是用於塊級元素的,若是觸發行內元素的hasLayout,就會讓行內元素擁有一些塊級元素的特性。
display:inline-block
行內的塊級元素,它有塊級元素的特色:可設置寬高、margin和padding值,也有行內元素的特色:不獨佔一行。
會觸發hasLayout。垂直方向的對齊,可設置形如 *vertical-align: -10px 來解決。
爲了實現E六、IE7和其餘瀏覽器都兼容display: inline-block,也存在必定問題:
- 它只能對行內元素實現 display: inline-block;不能夠是塊級元素。
- *vertical-align是針對IE對hack,這也是不友好的,能不用hack就儘可能不要使用hack。
雖然IE6和IE7不支持CSS設置爲display: inline-block,但事實上IE6和IE7的CSS解析引擎仍是有display: inline-block的,好比說img標籤和button標籤都具備display: inline-block的特性,能夠設置寬高但卻不獨佔一行。
float
會改變正常的文檔流排列,影響到周圍元素。
position: absolute 和 float: left或float: right 會隱式地改變display類型,不論以前是什麼類型的元素(display: none除外),都會讓元素以display: inline-block方式顯示:能夠設置寬高,默認寬帶並不佔滿父元素。
居中
- 水平居中
(1) 文本、圖片等行內元素的水平居中:給父元素設置 text-align: center
(2) 肯定寬度的塊級元素的水平居中:給元素設置 margin-left: auto 和 margin-right: auto
(3) 不肯定寬度的塊級元素的水平居中:
I. 使用table包裹,並給table設置margin: 0 auto; 優勢:作法巧妙。缺點:增長了無語義標籤,加深了標籤的嵌套層數
II. 使用display: inline/inline-block; 優勢:簡單明瞭,結構清晰。缺點:使用inline後變成了行內元素,缺乏了某些特性,如:width, hieght…
III. 使用position: relative,給父元素設置float、position:relative和left:50%,子元素設置position:relative和left:-50%。 優勢:結構清晰。缺點:position:relative會帶來一些反作用。
- 垂直居中
(1) 父元素高度不肯定的文本、圖片、塊級元素的垂直居中:給父容器設置相同的上下內邊距實現。
(2) 父元素高度肯定的單行文本的垂直居中:line-height: 父元素高度。
(3) 父元素高度肯定的多行文本、圖片、塊級元素垂直居中:
I. 使用table包裹,缺點:添加了無語義標籤,增長了嵌套層數。
II. 對支持 display: table-cell 的IE8 和 firefox 用 display: table-cell 和 vertical-align: middle 來實現居中,對不支持的IE6-7,使用特定格式的hack:給父子兩層元素分別設置{ *position: absolute; *top: 50% }和{ *position: relative; *top: -50% }來實現居中。缺點:使用來hack不利於維護,設置position: relative; position: absolute; 帶來一些反作用。
網格佈局
不管sidebar和main在樣式上誰左誰右,在html標籤上要保證main的標籤在sidebar以前被加載。
只在最外層的容器給定具體寬度,全部其餘容器的寬度均用百分比設置 –– 網格佈局。
z-index
z 軸在元素設置position爲absolute或relative後被激活。
設置負邊距可讓相鄰元素的位置產生重疊,誰浮在上面,取決於html標籤出現的前後,後出現的標籤浮於先出現的標籤之上。
IE6下的select遮擋問題,可以使用一樣大小的iframe遮住select。
爲避免組件的上下外邊距重合問題和IE的hasLaout引起的Bug,各模塊除特殊需求,一概採用margin-top設置上下外邊距。
Javascript
- 使用匿名函數將腳本包起來,能夠有效控制全局變量,避免衝突隱患。
- 讓JS不產生衝突,須要避免全局變量的泛濫,合理利用命名空間以及爲代碼添加必要的注視。
- DOMReady比window.onload更適合來調用初始化函數。
- 在頁面的最後,即</body>標籤以前再調用init函數,此時頁面內的DOM節點不必定都「加載完成」了,但必定都「生成」了,從而模擬DOMReady的效果。
- 將CSS放在頁頭,在載入html元素以前,先載入它們的樣式,這樣能夠避免html出現無樣式狀態;將javascript放在頁尾,先將網頁呈現給用戶,再來加載頁面內的腳本,避免javascript阻塞網頁的呈現,減小頁面空白的時間。
- base層和common層都是屬於框架級的,page層是屬於應用級的,它能夠調用base層的接口和common層的組件。
- 若是一個函數內某個因素很不穩定,咱們能夠將它從函數內部分離出來,以參數的形式傳入,從而將不穩定因素和函數解耦。
高品質的組件特色:
- 跨瀏覽器兼容
- 組件易用
- 組件可重用
- 組件可擴展
- 代碼組織有序,高內聚低耦合。
面向過程存在三方面問題:
- 數據和處理函數沒有直接的關聯,在執行操做的時候,咱們不但要選擇相應的處理函數,還要本身準備處理函數須要的數據,也就是說,在執行操做時,咱們須要同時關注處理函數和數據。
- 數據和處理函數都暴露在同一個做用域內,沒有私有和公有的概念,整個程序中全部的數據和處理函數均可以互相訪問。到了開發後期和維護階段,容易牽一髮而動全身,從而加大了修改難度。
- 面向過程的思惟方式是典型的計算機思惟方式––輸入數據給處理器,處理器內部執行運算,處理器返回結果。
面向對象:
- 在程序中咱們管「物件」叫作「對象」,對象由兩部分組成:「屬性」和「行爲」,對應客觀世界中物件的「狀態」和「動做」。
- 屬性本質實際上是個變量,也就是面向過程當中的數據,而行爲的本質實際上是函數,也就是面向過程當中的處理函數。不一樣的是,面向過程當中,數據和處理函數並無關聯起來,共同屬於某個物件。而面向對象將數據和處理函數定義到了一個對象的內部,做爲這個對象的屬性和行爲存在。
內聚:
指對象或類對外提供的接口很是簡單易懂,複雜的底層操做都封裝在對象或類的接口內部,對用戶透明。
用戶不用關心過多的底層細節,只需知道類提供了哪些接口,用戶知道的底層細節越少,對象的聚合程度就越高。
耦合:
指的是類與類之間關聯和依賴的程度,低耦合就是指類與類之間依賴的程度低,類與類通訊須要關聯的接口越少,耦合程度越低。
從大局上決定程序品質的,不是OOP,而是OOA和OOD。
OOA和OOD與具體語言無關,而OOP則直接跟語言相關。
Javascript是基於原型的語言,經過new 實例化出來的對象,其屬性和行爲來自於兩部分,一部分來自於構造函數,另外一部分來自於原型。
this關鍵字不管出如今構造函數中,仍是出如今原型中,指向的都是實例對象,經過this關鍵字,可讓屬性和方法在構造函數和原型間通訊。
在javascript中公有仍是私有是經過做用域實現的。
用this.XXX定義的屬性是公有的,而用 var XXX定義的屬性是私有的。
私有屬性的做用域只在類的構造函數中。
將全部屬性和行爲,不管公有仍是私有所有寫在構造函數裏,不推薦這麼作。由於在內存中一個類的原型只有一個,寫在原型中的行爲,能夠被全部實例所共享,實例化的時候,並不會在實例的內存中再複製一份,而寫在類裏的行爲,實例化的時候會在每一個實例裏複製一份。
把行爲寫在原型裏能夠減小內存消耗,沒有特殊緣由,推薦儘可能把行爲寫在原型裏。
寫在原型中的行爲必定是公有的,並且沒法訪問私有屬性。
在原型中定義私有行爲,但經過給屬性和行爲的名稱前面加上「_」來約定它是私有的,這是一種命名約定,它並不能真正實現行爲的私有,但它可以讓工程師知道它是設計成私有的,從而注意避開像公有行爲那樣調用它。
若是使用set方法來設置屬性,那麼咱們就有了監聽屬性valueChange的入口。
Javascript中繼承是要分別繼承構造函數和原型中的屬性和行爲的。
Javascript中function的兩種用法:
- 做爲函數存在,直接使用「()」進行調用,例如「function test() {}; test();」,test被用作函數,直接被「()」符號調用。其this指向window對象。
- 做爲類的構造函數存在,使用new調用,例如「function test() {}; new test();」,test做爲類的構造函數,經過new進行test類的實例化。其this指向的是實例對象。
能夠經過function對象上的call或者apply函數來修改函數的上下文this。
傳值和傳址:
- 若是是數值型、布爾型、字符型等基本數據類型,在進行賦值時會將數據複製一份,將複製的數據進行賦值,也就是一般所說的傳值。
- 若是時數組、hash對象等複雜數據類型,在進行賦值時會直接用內存地址賦值,而不是將數據複製一份,也就是一般所說的傳址。
prototype本質上也是個hash對象,因此直接用它賦值時會進行傳址。
Bird.prototype = new Animal(); // Bird.prototype.constructor指向了Animal
Bird.prototype.constructor = Bird; // Bird.prototype.constructor從新指向了Bird
只要是類就會有原型,無論它是自定義類仍是javascript的內置類。
內置類的方法能夠重寫,但屬性卻不能重寫。
代替直接修改內置類原型的作法,定義一個自定義類,將內置類的實例做爲參數傳給構造函數,在自定義類裏定義擴展方法。這種作法的思路是將內置類再封裝一層,以此保護內置類的原型不被污染。
定義在html標籤中的屬性,在javascript中有兩種獲取方式:
- 經過DOM節點對象的getAttribute方法。
- 經過DOM節點對象的屬性(兼容性更好)。
從兼容性考慮,建議對於常規屬性,統一使用 node.XXX的方式讀取,對於自定義屬性,統一使用 node.getAttribute(「XXX」)讀取。
將複雜類型的數據轉化成字符串,稱爲數據的序列化,其逆操做叫作數據的反序列化。
字符串的反序列化是經過eval函數實現的。
event對象在IE和Firefox下的表現是不一樣的。
在IE下,event是window對象的一個屬性,是在全局做用域下的,
而在Firefox裏,event對象做爲事件的參數存在。
在祖先節點上監聽事件(利用冒泡機制),可有效減少內存開銷。好比,jquery的
delegate()方法。