經常會在群里或論壇上看到有人問:“學習前端有什么捷徑?”,一般都是賣油翁式的回答:“無他唯手熟爾”。那么該如何讓手熟練呢?其實也就是該如何系統的學習前端。在本文中,我會結合自身的經歷,分享一下自己學習前端的過程,期間會穿插引用我過去各個階段所寫的博文。
## 一、啟蒙
  剛出來混的時候并不是專門做前端的,只是兼顧一下。那時候使用的編程軟件是微軟的Visual Stadio 2005,開發網頁都是拖封裝好的控件,做個系統后臺,使用的也是簡單的模板,改動HTML、JavaScript和CSS的機會也都比較少,這個時候其實對前端還沒有什么意識。
  然后過了一年,和朋友一起幫人做網站,那個時候就算是正式接觸前端了。有一件事印象很深刻,當時負責寫靜態頁面的朋友一直沒時間寫,于是我就想自己動手,但是完全無從下手,只能等待。在他寫了幾張頁面之后,我就開始研究他的源碼,這時候也僅僅是能看懂,再做點小修改,還無法獨立布局。
  在接下來的幾年里,陸續呆了多家公司,無一例外的我都會兼顧前端頁面,這也大大提升了我對前端的理解。不過,雖然做了那么多的頁面,但總有一種感覺,就是怎么每次布頁面都會碰到這樣那樣的問題,好像永遠都無法駕馭布局。現在想想,最主要的還是自己的地基不牢固,很多時候的布局并不難,但會涉及到很多細節,而這些細節很容易產生問題,例如CSS中的百分數計算規則、JavaScript中的全等和相等比較的區別、HTML元素表格的特點等等。這些在開發過程中都會碰到的,我那時候都是碰到了,再去翻資料,很是被動。如果事先就學會了或準備好了文檔的話,那么就能提升工作效率,減少開發周期。我將這個混沌的時期稱為啟蒙階段。
## 二、博學
  博學就是廣泛的學習,吸收知識。我當時首先學習的就是HTML、CSS和JavaScript,然后是數據結構、簡單的算法和網絡,接著是性能、設計模式和安全,最后還學習了調試工具、營銷推廣等各類知識,有的與編程有關,有的與編程無關。下面會依次列舉學習過程中所涉及的相關知識。
**1)HTML**
  HTML很容易被忽略,因為總覺得這個不難。其實的確不難,只是有時候會給人留坑,讓人踩進去防不勝防。比如常用的[表格](https://www.cnblogs.com/strick/p/3789114.html),在全方位的了解了它的特點之后,就能知道表格布局的缺點、它的屬性有哪些、它的CSS樣式該怎么重置、各個瀏覽器的呈現有何區別等。再比如[iframe](https://www.cnblogs.com/strick/p/3814872.html),在過去常用來異步上傳文件,在知道它的特性之后,就能明白其中的原理,碰到此類問題時就能游刃有余了。
  如果要系統的學習HTML的話,我推薦閱讀《[HTML5權威指南](https://book.douban.com/subject/25786074/)》、[MDN元素參數](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element),還有[W3C官方規范](https://www.w3.org/TR/html5/introduction.html),但這個比較拗口,理解起來會有難度。過去寫的一篇《[前端基礎學習分享](https://www.cnblogs.com/strick/p/4377213.html)》也可以參考。
**2)CSS**
  CSS要學的內容比HTML要多一些,在CSS2時代,提供的CSS屬性并不多,但自從CSS3發布之后,引入了眾多新屬性,大大提升了CSS的操控性。學習CSS首先要了解該屬性或概念是屬于CSS2還是CSS3,因為頁面要考慮瀏覽器的兼容性,即對CSS的支持度有差異,很多時候需要權衡。比如[動畫屬性](https://www.cnblogs.com/strick/category/847675.html),這是CSS3新增的,不僅能讓頁面生動真實,還能擺脫對Flash的依賴,遠離大段的JavaScript腳本。雖然效果很強大,但像IE8、IE9等瀏覽器并不支持,在這些瀏覽器中要么降級,要么干脆去掉這些特效。還有一些基礎概念,例如盒模型、BFC、選擇器、層疊、定位等,也是必須要了解的。
  如果要系統的學習CSS的話,我推薦閱讀《[CSS權威指南](https://book.douban.com/subject/2308234/)》,目前英文已經出到了第四版,中文的第四版今年肯定會出。第三版沒有講到CSS3的屬性,只是列舉了CSS2和CSS的基礎概念,講的還是很細的,可以將這本書當做詞典來用,需要的時候翻一下。這部書要細讀,才能發現平時不注意的CSS細節。當然,[MDN](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Reference)是肯定用的到的,也少不了[W3C規范](https://www.w3.org/TR/selectors-3/)。再分享一個,我平時會用到的在線[CSS參考手冊](http://css.doyoe.com/),如果開發PC端的網頁,還可以參考我以前的[一篇CSS分享](https://www.cnblogs.com/strick/p/4704356.html)。
  目前非常流行的CSS預處理器也有必要了解一下,例如[SASS](http://sass.bootcss.com/docs/sass-reference/)、[LESS](http://lesscss.cn/)等。簡單地說,它們就是為CSS設計的編程語言,可以減少工程師的開發量,提升效率。
**3)JavaScript**
  這是前端的核心,剛開始的話,先學習JavaScript的語法。我那時候不重視語法,拿來就是干,寫出來的代碼沒有JavaScript的味道,在看別人的代碼時,也經常會感到疑惑,不能理解他們的寫法,例如獲取變量默認值“a || b”、迭代方法forEach()、every()、some()等。學習語法首推《[JavaScript權威指南](https://book.douban.com/subject/10549733/)》、《[JavaScript高級程序設計](https://book.douban.com/subject/10546125/)》和《[深入理解ES6](https://book.douban.com/subject/27072230/)》,可以先讀權威指南,然后再去高級程序設計,它們都可以當成字典來用。深入理解ES6主要是講[ES6](https://www.ecma-international.org/ecma-262/6.0/)標準的,前面兩本目前的版本主要是講[ES5](https://www.ecma-international.org/ecma-262/5.1/)標準的,還有一套《[你不知道的JavaScript](https://book.douban.com/subject/26351021/)》系列,需要先有前面的基礎,然后再去讀的話,會好理解很多。關于ES6的學習,還可以關注我正在連載的《[ES6躬行記](https://www.cnblogs.com/strick/category/1372951.html)》系列,以基礎為主,力求簡單而又清晰不遺漏的介紹ES6的方方面面。各大瀏覽器對ES6的支持,可以參考[ECMAScript 6 compatibility table](http://kangax.github.io/compat-table/es6/)。
  我以前學習JavaScript沒有那么系統,都是根據項目中碰到了某個知識點,然后再去查相關的資料,例如《[觸屏touch事件記錄](https://www.cnblogs.com/strick/p/5155042.html)》、《[typeof、toString、instanceof、constructor與in](https://www.cnblogs.com/strick/p/4979949.html)》等。東一點西一點的這樣補,很是費勁。
**4)數據結構和算法**
  大學里有一門數據結構課,但當時感受不到它的威力,工作后才知道,數據結構是多么的重要。數據結構包括隊列、棧、鏈表、樹和圖等,具體有什么好處可以參考[這篇知乎](https://www.zhihu.com/question/29587605),里面有各種角度的回答。算法被稱為程序的靈魂,經典巨著就是《[算法導論](https://book.douban.com/subject/20432061/)》了,我算法太渣,看這本書蠻吃力的。
  我后面還專門去學習了一些數學,想著算法實現基于數學,那么先學習更底層的,可能就會好理解一點。之后就去讀了《[程序員的數學思維修煉(趣味解讀)](https://book.douban.com/subject/25854719/)》、《[生活中的數學](https://book.douban.com/subject/26646345/)》、《[生活中的概率趣事](https://book.douban.com/subject/26220204/)》和《[枕邊算法書](https://book.douban.com/subject/30163021/)》等書。大學里還學過一門離散數學,當時覺得枯燥而無用,進了社會后才知道其實很有用,它可以提高抽象思維和嚴格的邏輯推理能力。現在還在讀大學的工科生,真的很有必要將數學打扎實,對以后會有很大的幫助。
**5)網絡**
  “[網絡](https://www.cnblogs.com/strick/category/832640.html)”我只學習了與我的工作相關的內容,例如HTTP、TCP、HTTPS等協議。做前端,至少得看得懂基本的報文,理解TCP的連接、HTTPS的安全性、HTTP的特點等概念。知道這些后,就能方便自己在調試頁面的時候,定位BUG,同時也能更和諧的與后端溝通,例如你調個接口,但是沒有數據返回,你可以將報文截圖,然后發給后端,這樣的話,他們就能知道請求和響應的信息,方便他們定位問題。
  大學的網絡課很枯燥,等于沒學。工作后開始買些網絡相關的書看,有《[圖解HTTP](https://book.douban.com/subject/25863515/)》和《[圖解TCP/IP](https://book.douban.com/subject/24737674/)》,這兩本比較通俗,容易消化。還有一本加《[HTTP權威指南](https://book.douban.com/subject/10746113/)》,這本非常專業,內容也很全,就是理解起來費勁一點,可當字典來使用。
**6)工具**
  作為前端開發,除了要會使用瀏覽器的Debugger工具之外,還需要會些其它的工具。首推的是Windows上的[Fiddler](https://www.cnblogs.com/strick/p/4570006.html),Mac上可用Charles替代,Fiddler很適合移動端開發,因為手機上的瀏覽器不像PC上的Chrome、Firefox那樣可以打開調試工具,它們在移動端是不存在。如果要抓取手機訪問頁面時的通信信息,就得借助Fiddler了。再推[Wireshark](https://www.cnblogs.com/strick/p/6344486.html)網絡抓包工具,這個工具抓取的信息要比Fiddler更加底層,例如能抓取TCP三次握手的通信。
  前端開發目前都需要自動化構建化工具,例如[Gulp](https://www.cnblogs.com/strick/p/5151714.html)、[Webpack](https://webpack.docschina.org/concepts/)等。構建工具可以編譯JavaScript、CSS和HTML,例如將ES6代碼編譯成瀏覽器支持的ES5代碼、SASS文件編譯成普通的CSS文件、合并和壓縮JavaScript腳本等,改變了前端的開發模式,解放生產力、提高生產效率。
  計算機學習需要上機操作,上面所列的知識都需要上機驗證,古語云:“紙上得來終覺淺,絕知此事要躬行”,只有真的做了,才能有更深刻的體會。性能、設計模式和安全等知識,對于初學者來說還不適合學習,目前還是以打基礎為核心目標。
## 三、慎思
  慎思就是謹慎的思考,學習不是填鴨式的,需要經常思考,這樣才能進步。
**1)技術引入**
  我以前每次學到點新技術,就迫不及待的想引入到項目中,例如2011年的時候剛學Ajax,就把整個網站的數據交互用Ajax實現,頁面渲染就用簡陋的字符串拼接完成,代碼丑陋至極(詳見《[憶2011年的秋天](https://www.cnblogs.com/strick/p/10007237.html)》)。在項目經歷越來越多之后,就會謹慎的看待新技術。對新技術保持旺盛的求知欲,是件毋庸置疑的好事兒,但是把它引用到項目中,就得斟酌一下了,例如要考慮可維護性、與之前代碼的兼容度、性能和學習成本等方面。
  如果工作中的項目不行,那么可以自己開辟一個開源項目,把想要的新技術加進來。例如自己以前學習了CSS3,就試著做了個[在線簡歷](https://www.cnblogs.com/strick/category/907450.html),用到了陰影、圓角、動畫等CSS3新屬性。
**2)知其然而所以然**
  “[jQuery](https://jquery.com/)”曾經在前端界有著舉足輕重的地位,甚至影響了W3C標準的制訂,以前很好奇jQuery是怎么運轉的,于是就去查看里面的源碼,奈何水平有限,很難讀懂。而在移動端有個與之類似的精簡DOM庫:[Zepto.js](https://zeptojs.com/),這個庫的代碼量少了很多,還是可以讀懂的。接著我就試著寫一個類似的庫,起名叫“[iSelector](https://www.cnblogs.com/strick/p/5357210.html)”。為何要重復造這個輪子,因為在造的過程中,能夠了解到以前不知道的Element、Array等相關的方法或屬性,加深對DOM的理解,而且在使用Zepto的時候,能夠選取最合適的方法。還有一點在《[制造自己的榫卯](https://www.cnblogs.com/strick/p/5347551.html)》中曾提到過,即應用自己封裝的函數,就好比榫卯,拿來即可用,而不需要特定的釘子。
  除了造輪子之外,研究開源庫的源碼也是一種理解原理的途徑,例如手勢插件[Hammer.js的分析](https://www.cnblogs.com/strick/category/907457.html),[開源網站流量統計系統Piwik源碼分析](https://www.cnblogs.com/strick/p/9599023.html)等。
**3)舉一反三**
  對于同一個問題,會有多種解決方案。在平時的學習中,也有必要舉一反三,這樣在實際應用時,就能選取最優的方案。自己曾經研究過[Loading(加載)動畫效果](https://www.cnblogs.com/strick/p/4551818.html),搜集了網上的4種實現方式,分別是PNG圖片+CSS3動畫、spin.js、Ladda和Sonic.js。這是一個有趣的過程,不僅可以了解到它們各自的優缺點,還能了解它們不同的實現原理。
**4)開發習慣**
  開發也是學習的過程,總結出自己獨有的開發習慣,能夠提升自己的工作效率。我自己在開發中遇到技術或工具都會做個總結,比如項目中用到了HTML5新增的[Canvas元素](https://www.cnblogs.com/strick/category/847676.html),我就會搜集它的屬性、方法和第三方庫,再將它的實際應用(如海報生成、圖像裁剪、文字合成等)從項目中抽象出來,整理成文。再比如以前為了撰寫在線文檔而使用了靜態頁面生成器Jekyll,在事后寫了[兩篇總結](https://www.cnblogs.com/strick/category/823089.html)(關于安裝、配置和應用),以備自己日后閱讀。
  對于工作中遇到的問題,我也會記錄下來,例如[IE6的BUG記錄](https://www.cnblogs.com/strick/p/3776378.html),我入行的早期還是IE6橫行的時代,兼容IE6是必須的,它那千奇百怪的問題折磨著一代人。
  程序員要時刻充電,閱讀書籍是最好的一個途徑之一。每次在閱讀完整本書或某個章節后,[我也喜歡做個總結](https://www.cnblogs.com/strick/p/10053205.html),可以簡單的把自己感興趣的內容摘抄下來,也可以根據書中的內容做一次實踐,還可以做簡單的記錄匯總。
  我的開發習慣簡單的概括就是:總結和記錄。
## 四、篤行
  篤行就是學以致用,踐履所學,做到知行合一。
**1)PrimusUI**
  在學習了CSS3后,為了能使用到那些新屬性,于是就設計了一個UI庫,名字叫“[PrimusUI](https://www.cnblogs.com/strick/p/5536321.html)”。這是一個輕量、響應式、移動端、易上手、可定制的UI庫。包含文本、表單、列表、網格等13個模塊,涉及伸縮盒、自定義字體、陰影、偽元素等屬性。
**2)制作插件**
  要制作一個插件不僅需要懂得HTML和CSS,還要熟悉JavaScript。我制作的[幾個插件](https://www.cnblogs.com/strick/category/847678.html)都是從實際項目中剝離封裝出來的,例如[移動端H5通用表單驗證插件](https://www.cnblogs.com/strick/p/6801453.html),可驗證文本框的字數、格式等,并且將驗證規則作為控件的一個屬性,寫在控件的html中,有點MVVM模式的味道。
**3)抽象共性**
  平時我還會想各種方式來提升自己的工作效率,以前曾整理出[網站的通用部分](https://www.cnblogs.com/strick/p/3826485.html),對其中的[注冊頁面](https://www.cnblogs.com/strick/p/3871374.html)做了詳細的分解,包括提示、圖標、限制和特效等,準備了這些代碼,在以后需要時,就能拿來做更新,而不用再重新編寫。
**4)表述**
  很多時候看了不代表就懂了,得用自己的語言描述某個技術或概念,一直到自己覺得準確了為止,這個過程也能檢驗出自己對知識的理解到底處于哪個深度。還可以將自己的體會整理成一套符合自己需求的知識體系。
*****
> 已建立一個微信前端交流群,如要進群,請先加微信號freedom20180706或掃描下面的二維碼,請求中需注明“看云加群”,在通過請求后就會把你拉進來。還搜集整理了一套[面試資料](https://github.com/pwstrick/daily),歡迎閱讀。

- ES6
- 1、let和const
- 2、擴展運算符和剩余參數
- 3、解構
- 4、模板字面量
- 5、對象字面量的擴展
- 6、Symbol
- 7、代碼模塊化
- 8、數字
- 9、字符串
- 10、正則表達式
- 11、對象
- 12、數組
- 13、類型化數組
- 14、函數
- 15、箭頭函數和尾調用優化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、類
- 21、類的繼承
- 22、Promise
- 23、Promise的靜態方法和應用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基礎實踐
- 3、WebRTC視頻通話
- 4、Web音視頻基礎
- CSS進階
- 1、CSS基礎拾遺
- 2、偽類和偽元素
- 3、CSS屬性拾遺
- 4、浮動形狀
- 5、漸變
- 6、濾鏡
- 7、合成
- 8、裁剪和遮罩
- 9、網格布局
- 10、CSS方法論
- 11、管理后臺響應式改造
- React
- 1、函數式編程
- 2、JSX
- 3、組件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表單
- 8、樣式
- 9、組件通信
- 10、高階組件
- 11、Redux基礎
- 12、Redux中間件
- 13、React Router
- 14、測試框架
- 15、React Hooks
- 16、React源碼分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基礎
- 4、webpack進階
- 5、Git
- 6、Fiddler
- 7、自制腳手架
- 8、VSCode插件研發
- 9、WebView中的頁面調試方法
- Vue.js
- 1、數據綁定
- 2、指令
- 3、樣式和表單
- 4、組件
- 5、組件通信
- 6、內容分發
- 7、渲染函數和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、數據類型
- 2、接口
- 3、類
- 4、泛型
- 5、類型兼容性
- 6、高級類型
- 7、命名空間
- 8、裝飾器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系統和網絡
- 3、命令行工具
- 4、自建前端監控系統
- 5、定時任務的調試
- 6、自制短鏈系統
- 7、定時任務的進化史
- 8、通用接口
- 9、微前端實踐
- 10、接口日志查詢
- 11、E2E測試
- 12、BFF
- 13、MySQL歸檔
- 14、壓力測試
- 15、活動規則引擎
- 16、活動配置化
- 17、UmiJS版本升級
- 18、半吊子的可視化搭建系統
- 19、KOA源碼分析(上)
- 20、KOA源碼分析(下)
- 21、花10分鐘入門Node.js
- 22、Node環境升級日志
- 23、Worker threads
- 24、低代碼
- 25、Web自動化測試
- 26、接口攔截和頁面回放實驗
- 27、接口管理
- 28、Cypress自動化測試實踐
- 29、基于Electron的開播助手
- Node.js精進
- 1、模塊化
- 2、異步編程
- 3、流
- 4、事件觸發器
- 5、HTTP
- 6、文件
- 7、日志
- 8、錯誤處理
- 9、性能監控(上)
- 10、性能監控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 監控系統
- 1、SDK
- 2、存儲和分析
- 3、性能監控
- 4、內存泄漏
- 5、小程序
- 6、較長的白屏時間
- 7、頁面奔潰
- 8、shin-monitor源碼分析
- 前端性能精進
- 1、優化方法論之測量
- 2、優化方法論之分析
- 3、瀏覽器之圖像
- 4、瀏覽器之呈現
- 5、瀏覽器之JavaScript
- 6、網絡
- 7、構建
- 前端體驗優化
- 1、概述
- 2、基建
- 3、后端
- 4、數據
- 5、后臺
- Web優化
- 1、CSS優化
- 2、JavaScript優化
- 3、圖像和網絡
- 4、用戶體驗和工具
- 5、網站優化
- 6、優化閉環實踐
- 數據結構與算法
- 1、鏈表
- 2、棧、隊列、散列表和位運算
- 3、二叉樹
- 4、二分查找
- 5、回溯算法
- 6、貪心算法
- 7、分治算法
- 8、動態規劃
- 程序員之路
- 大學
- 2011年
- 2012年
- 2013年
- 2014年
- 項目反思
- 前端基礎學習分享
- 2015年
- 再一次項目反思
- 然并卵
- PC網站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端學習之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 2024年
- 日志
- 2020