一、启蒙
刚出来混的时候并不是专门做前端的,只是兼顾一下。那时候使用的编程软件是微软的Visual Stadio 2005,开发网页都是拖封装好的控件,做个系统后台,使用的也是简单的模板,改动HTML、JavaScript和CSS的机会也都比较少,这个时候其实对前端还没有什么意识。
然后过了一年,和朋友一起帮人做网站,那个时候就算是正式接触前端了。有一件事印象很深刻,当时负责写静态页面的朋友一直没时间写,于是我就想自己动手,但是完全无从下手,只能等待。在他写了几张页面之后,我就开始研究他的源码,这时候也仅仅是能看懂,再做点小修改,还无法独立布局。
在接下来的几年里,陆续呆了多家公司,无一例外的我都会兼顾前端页面,这也大大提升了我对前端的理解。不过,虽然做了那么多的页面,但总有一种感觉,就是怎么每次布页面都会碰到这样那样的问题,好像永远都无法驾驭布局。现在想想,最主要的还是自己的地基不牢固,很多时候的布局并不难,但会涉及到很多细节,而这些细节很容易产生问题,例如CSS中的百分数计算规则、JavaScript中的全等和相等比较的区别、HTML元素表格的特点等等。这些在开发过程中都会碰到的,我那时候都是碰到了,再去翻资料,很是被动。如果事先就学会了或准备好了文档的话,那么就能提升工作效率,减少开发周期。我将这个混沌的时期称为启蒙阶段。
二、博学
博学就是广泛的学习,吸收知识。我当时首先学习的就是HTML、CSS和JavaScript,然后是数据结构、简单的算法和网络,接着是性能、设计模式和安全,最后还学习了调试工具、营销推广等各类知识,有的与编程有关,有的与编程无关。下面会依次列举学习过程中所涉及的相关知识。
1)HTML
HTML很容易被忽略,因为总觉得这个不难。其实的确不难,只是有时候会给人留坑,让人踩进去防不胜防。比如常用的表格,在全方位的了解了它的特点之后,就能知道表格布局的缺点、它的属性有哪些、它的CSS样式该怎么重置、各个浏览器的呈现有何区别等。再比如iframe,在过去常用来异步上传文件,在知道它的特性之后,就能明白其中的原理,碰到此类问题时就能游刃有余了。
如果要系统的学习HTML的话,我推荐阅读《HTML5权威指南》、MDN元素参数,还有W3C官方规范,但这个比较拗口,理解起来会有难度。过去写的一篇《前端基础学习分享》也可以参考。
2)CSS
CSS要学的内容比HTML要多一些,在CSS2时代,提供的CSS属性并不多,但自从CSS3发布之后,引入了众多新属性,大大提升了CSS的操控性。学习CSS首先要了解该属性或概念是属于CSS2还是CSS3,因为页面要考虑浏览器的兼容性,即对CSS的支持度有差异,很多时候需要权衡。比如动画属性,这是CSS3新增的,不仅能让页面生动真实,还能摆脱对Flash的依赖,远离大段的JavaScript脚本。虽然效果很强大,但像IE8、IE9等浏览器并不支持,在这些浏览器中要么降级,要么干脆去掉这些特效。还有一些基础概念,例如盒模型、BFC、选择器、层叠、定位等,也是必须要了解的。
如果要系统的学习CSS的话,我推荐阅读《CSS权威指南》,目前英文已经出到了第四版,中文的第四版今年肯定会出。第三版没有讲到CSS3的属性,只是列举了CSS2和CSS的基础概念,讲的还是很细的,可以将这本书当做词典来用,需要的时候翻一下。这部书要细读,才能发现平时不注意的CSS细节。当然,MDN是肯定用的到的,也少不了W3C规范。再分享一个,我平时会用到的在线CSS参考手册,如果开发PC端的网页,还可以参考我以前的一篇CSS分享。
目前非常流行的CSS预处理器也有必要了解一下,例如SASS、LESS等。简单地说,它们就是为CSS设计的编程语言,可以减少工程师的开发量,提升效率。
3)JavaScript
这是前端的核心,刚开始的话,先学习JavaScript的语法。我那时候不重视语法,拿来就是干,写出来的代码没有JavaScript的味道,在看别人的代码时,也经常会感到疑惑,不能理解他们的写法,例如获取变量默认值“a || b”、迭代方法forEach()、every()、some()等。学习语法首推《JavaScript权威指南》、《JavaScript高级程序设计》和《深入理解ES6》,可以先读权威指南,然后再去高级程序设计,它们都可以当成字典来用。深入理解ES6主要是讲ES6标准的,前面两本目前的版本主要是讲ES5标准的,还有一套《你不知道的JavaScript》系列,需要先有前面的基础,然后再去读的话,会好理解很多。关于ES6的学习,还可以关注我正在连载的《ES6躬行记》系列,以基础为主,力求简单而又清晰不遗漏的介绍ES6的方方面面。各大浏览器对ES6的支持,可以参考ECMAScript 6 compatibility table。
我以前学习JavaScript没有那么系统,都是根据项目中碰到了某个知识点,然后再去查相关的资料,例如《触屏touch事件记录》、《typeof、toString、instanceof、constructor与in》等。东一点西一点的这样补,很是费劲。
4)数据结构和算法
大学里有一门数据结构课,但当时感受不到它的威力,工作后才知道,数据结构是多么的重要。数据结构包括队列、栈、链表、树和图等,具体有什么好处可以参考这篇知乎,里面有各种角度的回答。算法被称为程序的灵魂,经典巨著就是《算法导论》了,我算法太渣,看这本书蛮吃力的。
我后面还专门去学习了一些数学,想着算法实现基于数学,那么先学习更底层的,可能就会好理解一点。之后就去读了《程序员的数学思维修炼(趣味解读)》、《生活中的数学》、《生活中的概率趣事》和《枕边算法书》等书。大学里还学过一门离散数学,当时觉得枯燥而无用,进了社会后才知道其实很有用,它可以提高抽象思维和严格的逻辑推理能力。现在还在读大学的工科生,真的很有必要将数学打扎实,对以后会有很大的帮助。
5)网络
网络我只学习了与我的工作相关的内容,例如HTTP、TCP、HTTPS等协议。做前端,至少得看得懂基本的报文,理解TCP的连接、HTTPS的安全性、HTTP的特点等概念。知道这些后,就能方便自己在调试页面的时候,定位BUG,同时也能更和谐的与后端沟通,例如你调个接口,但是没有数据返回,你可以将报文截图,然后发给后端,这样的话,他们就能知道请求和响应的信息,方便他们定位问题。
大学的网络课很枯燥,等于没学。工作后开始买些网络相关的书看,有《图解HTTP》和《图解TCP/IP》,这两本比较通俗,容易消化。还有一本加《HTTP权威指南》,这本非常专业,内容也很全,就是理解起来费劲一点,可当字典来使用。
6)工具
作为前端开发,除了要会使用浏览器的Debugger工具之外,还需要会些其它的工具。首推的是Windows上的Fiddler,Mac上可用Charles替代,Fiddler很适合移动端开发,因为手机上的浏览器不像PC上的Chrome、Firefox那样可以打开调试工具,它们在移动端是不存在。如果要抓取手机访问页面时的通信信息,就得借助Fiddler了。再推Wireshark网络抓包工具,这个工具抓取的信息要比Fiddler更加底层,例如能抓取TCP三次握手的通信。
前端开发目前都需要自动化构建化工具,例如Gulp、Webpack等。构建工具可以编译JavaScript、CSS和HTML,例如将ES6代码编译成浏览器支持的ES5代码、SASS文件编译成普通的CSS文件、合并和压缩JavaScript脚本等,改变了前端的开发模式,解放生产力、提高生产效率。
计算机学习需要上机操作,上面所列的知识都需要上机验证,古语云:“纸上得来终觉浅,绝知此事要躬行”,只有真的做了,才能有更深刻的体会。性能、设计模式和安全等知识,对于初学者来说还不适合学习,目前还是以打基础为核心目标。
三、慎思
慎思就是谨慎的思考,学习不是填鸭式的,需要经常思考,这样才能进步。
1)技术引入
我以前每次学到点新技术,就迫不及待的想引入到项目中,例如2011年的时候刚学Ajax,就把整个网站的数据交互用Ajax实现,页面渲染就用简陋的字符串拼接完成,代码丑陋至极(详见《忆2011年的秋天》)。在项目经历越来越多之后,就会谨慎的看待新技术。对新技术保持旺盛的求知欲,是件毋庸置疑的好事儿,但是把它引用到项目中,就得斟酌一下了,例如要考虑可维护性、与之前代码的兼容度、性能和学习成本等方面。
如果工作中的项目不行,那么可以自己开辟一个开源项目,把想要的新技术加进来。例如自己以前学习了CSS3,就试着做了个在线简历,用到了阴影、圆角、动画等CSS3新属性。
2)知其然而所以然
jQuery曾经在前端界有着举足轻重的地位,甚至影响了W3C标准的制订,以前很好奇jQuery是怎么运转的,于是就去查看里面的源码,奈何水平有限,很难读懂。而在移动端有个与之类似的精简DOM库:Zepto.js,这个库的代码量少了很多,还是可以读懂的。接着我就试着写一个类似的库,起名叫“iSelector”。为何要重复造这个轮子,因为在造的过程中,能够了解到以前不知道的Element、Array等相关的方法或属性,加深对DOM的理解,而且在使用Zepto的时候,能够选取最合适的方法。还有一点在《制造自己的榫卯》中曾提到过,即应用自己封装的函数,就好比榫卯,拿来即可用,而不需要特定的钉子。
除了造轮子之外,研究开源库的源码也是一种理解原理的途径,例如手势插件Hammer.js的分析,开源网站流量统计系统Piwik源码分析等。
3)举一反三
对于同一个问题,会有多种解决方案。在平时的学习中,也有必要举一反三,这样在实际应用时,就能选取最优的方案。自己曾经研究过Loading(加载)动画效果,搜集了网上的4种实现方式,分别是PNG图片+CSS3动画、spin.js、Ladda和Sonic.js。这是一个有趣的过程,不仅可以了解到它们各自的优缺点,还能了解它们不同的实现原理。
4)开发习惯
开发也是学习的过程,总结出自己独有的开发习惯,能够提升自己的工作效率。我自己在开发中遇到技术或工具都会做个总结,比如项目中用到了HTML5新增的Canvas元素,我就会搜集它的属性、方法和第三方库,再将它的实际应用(如海报生成、图像裁剪、文字合成等)从项目中抽象出来,整理成文。再比如以前为了撰写在线文档而使用了静态页面生成器Jekyll,在事后写了两篇总结(关于安装、配置和应用),以备自己日后阅读。
对于工作中遇到的问题,我也会记录下来,例如IE6的BUG记录,我入行的早期还是IE6横行的时代,兼容IE6是必须的,它那千奇百怪的问题折磨着一代人。
程序员要时刻充电,阅读书籍是最好的一个途径之一。每次在阅读完整本书或某个章节后,我也喜欢做个总结,可以简单的把自己感兴趣的内容摘抄下来,也可以根据书中的内容做一次实践,还可以做简单的记录汇总。
我的开发习惯简单的概括就是:总结和记录。
四、笃行
笃行就是学以致用,践履所学,做到知行合一。
1)PrimusUI
在学习了CSS3后,为了能使用到那些新属性,于是就设计了一个UI库,名字叫“PrimusUI”。这是一个轻量、响应式、移动端、易上手、可定制的UI库。包含文本、表单、列表、网格等13个模块,涉及伸缩盒、自定义字体、阴影、伪元素等属性。
2)制作插件
要制作一个插件不仅需要懂得HTML和CSS,还要熟悉JavaScript。我制作的几个插件都是从实际项目中剥离封装出来的,例如移动端H5通用表单验证插件,可验证文本框的字数、格式等,并且将验证规则作为控件的一个属性,写在控件的html中,有点MVVM模式的味道。
3)抽象共性
平时我还会想各种方式来提升自己的工作效率,以前曾整理出网站的通用部分,对其中的注册页面做了详细的分解,包括提示、图标、限制和特效等,准备了这些代码,在以后需要时,就能拿来做更新,而不用再重新编写。
4)表述
很多时候看了不代表就懂了,得用自己的语言描述某个技术或概念,一直到自己觉得准确了为止,这个过程也能检验出自己对知识的理解到底处于哪个深度。还可以将自己的体会整理成一套符合自己需求的知识体系。