在“开篇词”中,我和你简单回顾了前端行业的发展,到现在为止,前端工程师已经成为研发体系中的重要岗位之一。可是,与此相对的是,我发现极少或者几乎没有大学的计算机专业愿意开设前端课程,更没有系统性的教学方案出现。大部分前端工程师的知识,其实都是来自于实践和工作中零散的学习。
这样的现状就引发了一系列的问题。
首先是前端的基础知识,常常有一些工作多年的工程师,在看到一些我认为很基础的JavaScript语法的时候,还会惊呼“居然可以这样”。是的,基础知识的欠缺会让你束手束脚,更限制你解决问题的思路。
其次,技术上存在短板,就会导致前端开发者的上升通道不甚顺畅。特别是一些小公司的程序员,只能靠自己摸索,这样就很容易陷入重复性劳动的陷阱,最终耽误自己的职业发展。
除此之外,前端工程师也会面临技术发展问题带来的挑战。前端社区高度活跃,前端标准也在快速更新,这样蓬勃发展对技术来说无疑是好事,但是副作用也显而易见,它使得前端工程师的学习压力变得很大。
我们就拿JavaScript标准来说,ES6中引入的新特性超过了过去十年的总和,新特性带来的实践就更多了,仅仅是一个Proxy特性的引入,就支持了VueJS从2.0到3.0的内核原理完全升级。
缺少系统教育+技术快速革新,在这样的大环境下,前端工程师保持自学能力就显得尤其重要了。
那么,前端究竟应该怎么学呢?我想,我可以简单分享一下自己的经验。
首先是0基础入门的同学,你可以读几本经典的前端教材,比如《JavaScript高级程序设计》《精通CSS》等书籍,去阅读一些参考性质的网站也是不错的选项,比如MDN。
如果你至少已经有了1年以上的工作经验,希望在技术上有一定突破,那么,这个专栏就可以是你技术进阶的一个选项了。
在这个专栏中,我希望传达的不仅仅是具体的知识点,还有体系架构和学习方法。我希望达到三个目标:
在开始具体的知识讲解之前,这篇文章中,我想先来谈两个前端学习方法。
第一个方法是建立自己的知识架构,并且在这个架构上,不断地进行优化。
我们先来讲讲什么叫做知识架构?我们可以把它理解为知识的“目录”或者索引,它能够帮助我们把零散的知识组织起来,也能够帮助我们发现一些知识上的盲区。
当然,知识的架构是有优劣之分的,最重要的就是逻辑性和完备性。
我们来思考一个问题,如果我们要给JavaScript知识做一个顶层目录,该怎么做呢?
如果我们把一些特别流行的术语和问题,拼凑起来,可能会变成这样:
这其实不是我们想要的结果,因为这些知识点之间,没有任何逻辑关系。它们既不是并列关系,又不是递进关系,合在一起,也就没有任何意义。这样的知识架构,无法帮助我们去发现问题和理解问题。
如果让我来做,我会这样划分:
为什么这样分呢,因为对于任何计算机语言来说,必定是“用规定的文法,去表达特定语义,最终操作运行时的”一个过程。
这样,JavaScript的任何知识都不会出现在这个范围之外,这是知识架构的完备性。我们再往下细分一个层级,就变成了这个样子:
我来解释一下这个划分。
文法可以分成词法和语法,这来自编译原理的划分,同样是完备的。语义则跟语法具有一一对应关系,这里暂时不区分。
对于运行时部分,这个划分保持了完备性,我们都知道:程序 = 算法 + 数据结构,那么,对运行时来说,类型就是数据结构,执行过程就是算法。
当我们再往下细分的时候,就会看到熟悉的概念了,词法中有各种直接量、关键字、运算符,语法和语义则是表达式、语句、函数、对象、模块,类型则包含了对象、数字、字符串等……
这样逐层向下细分,知识框架就初见端倪了。在顶层和大结构上,我们通过逻辑来保持完备性。如果继续往下,就需要一些技巧了,我们可以寻找一些线索。
比如在JavaScript标准中,有完整的文法定义,它是具有完备性的,所以我们可以根据它来完成,我们还可以根据语法去建立语义的知识架构。实际上,因为JavaScript有一份统一的标准,所以相对来说不太困难。
如果是浏览器中的API,那就困难了,它们分布在w3c的各种标准当中,非常难找。但是我们要想找到一些具有完备性的线索,也不是没有办法。我喜欢的一个办法,就是用实际的代码去找:for in 遍历window的属性,再去找它的内容。
我想,学习的过程,实际上就是知识架构不断进化的过程,通过知识架构的自然延伸,我们可以更轻松地记忆一些原本难以记住的点,还可以发现被忽视的知识盲点。
建立知识架构,同样有利于面试,没人能够记住所有的知识,当不可避免地谈到一个记不住的知识,如果你能快速定位到它在知识架构中的位置,把一些相关的点讲出来,我想,这也能捞回不少分。(关于前端具体的知识架构,我会在02篇文章中详细讲解。)
第二个方法,我把它称作追本溯源。
有一些知识,背后有一个很大的体系,例如,我们对比一下CSS里面的两个属性:
虽然都是“属性”,但是它们背后的知识量完全不同,opacity是个非常单纯的数值,表达的意思也很清楚,而display的每一个取值背后都是一个不同的布局体系。我们要讲清楚display,就必须关注正常流(Normal Flow)、关注弹性布局系统以及grid这些内容。
还有一些知识,涉及的概念本身经历了各种变迁,变得非常复杂和有争议性,比如MVC,从1979年至今,概念变化非常大,MVC的定义几乎已经成了一段公案,我曾经截取了MVC原始论文、MVP原始论文、微软MSDN、Apple开发者文档,这些内容里面,MVC画的图、箭头和解释都完全不同。
这种时候,就是我们做一些考古工作的时候了。追本溯源,其实就是关注技术提出的背景,关注原始的论文或者文章,关注作者说的话。
操作起来也非常简单:翻翻资料(一般wiki上就有)找找历史上的文章和人物,再顺藤摸瓜翻出来历史资料就可以了,如果翻出来的是历史人物(幸亏互联网的历史不算悠久),你也可以试着发封邮件问问。
这个过程,可以帮助我们理解一些看上去不合理的东西,有时候还可以收获一些趣闻,比如JavaScript之父 Brendan Eich 曾经在Wikipedia的讨论页上解释JavaScript最初想设计一个带有prototype的scheme,结果受到管理层命令把它弄成像Java的样子(如果你再挖的深一点,甚至能找到他对某位“尖头老板”的吐槽)。
根据这么一句话,我们再去看看scheme,看看Java,再看看一些别的基于原型的语言,我们就可以理解为什么JavaScript是现在这个样子了:函数是一等公民,却提供了new this instanceof等特性,甚至抄来了Java的getYear这样的Bug。
今天我带你探索了前端的学习路径,并提出了两个学习方法:你要试着建立自己的知识架构,除此之外,还要学会追本溯源,找到知识的源头。
这个专栏中,我并不奢望通过短短的40篇专栏,事无巨细地把前端的所有知识都罗列清楚,这本身是MDN这样的参考手册的工作。但是,我希望通过这个专栏,把前端技术背后的设计原理和知识体系讲清楚,让你能对前端技术产生整体认知,这样才能够在未来汹涌而来的新技术中保持领先的状态。
接下来的3个月里,我将带你重新认识前端。
我自己是在2006年开始接触前端的。现在回想起来,那会儿前端还处于史前的“青铜时代”,甚至网页的主要交互都还是依靠切换超链接来完成的。
那时候,谷歌刚刚基于Ajax发布的Gmail也没多久,虽然这项伟大的技术标志着Web 1.0(静态网页)到Web 2.0(动态网页)的迈进,但在国内依然少有人懂,如果当时谁可以对这项技术侃侃而谈,那简直就是大神的级别了。
当时我还是个学生,喜欢前端纯粹是兴趣使然。那时我混黑白棋社区,想着给黑白棋界面写插件,但自己又不懂界面相关的知识,于是开始通过各种方式学习前端。
真想学的时候才发现网络上的前端资料很是稀缺,所以我基本上都是先从图书馆借书,然后再在电脑上跑案例验证这样的方式来学习的,现在想起来,还真是一段艰难的岁月。
当然,这段经历也为我日后的前端生涯悄悄埋下了一颗种子,我逐渐开始把自己的职业规划路线放在了前端上。
这在当时是个不可思议的想法,因为那时的前端岗位不论从收入上还是在职责上,都远落后于其他岗位。但是,我基于对技术发展趋势的判断,认为前端在未来会越来越重要。
2008年,我毕业了,也很幸运地得到了一个既能发挥我的C++长处,又能兼顾前端发展规划的职位:微软北京的软件开发工程师,恰好负责的是Windows CE上的IE浏览器开发,在这里,我接触到了当时最先进的软件工程体系,并且积累了很多UI架构经验。
两年后,我加入了盛大做电子书,负责电子书的文本排版工作,这个工作是一个既写底层又写JavaScript的岗位,同时排版引擎也是浏览器的重要组成部分,也让我对浏览器的工作原理有了更深入的理解。
在盛大后期,我加入了WebOS项目,负责前端框架,我开始基于移动的角度思考前端交互和框架,这份工作让离我前端又近了一步。
但是很遗憾,因为种种原因,我在微软和盛大的几个项目都不算成功,除了电子书实际上市但销量不高,Windows CE 7.0 和盛大的 WebOS 都在公司内部夭折。
自己亲手构建的产品,却因为非技术原因没有服务到最终用户,对我来说,是件非常遗憾的事情。不过,这段时间,也让我更加确信前端技术的价值。
回过来看,那几年,前端技术开始了它的大踏步发展,那一段时间,可以说是前端的“白银时代”。最直观的表现之一就是前端逐步从后端分离了出来,它的代码也变得复杂了起来,还需要保存数据、处理数据、生成视图等等。
悄然之间,我发现前端已经从零散的“工序”逐步发展成为有体系和发展目标的职能,同时,在越来越大的前端团队中,工程化的思想也逐渐萌芽。我深有感触,前端已经不再是别人眼中的“小菜一碟”了。
在这样的行业背景里,从盛大离职后,我加入了阿里巴巴做手机淘宝开发,这也是我首次从事真正的前端工作。
在手机淘宝,前端团队的各种基础设施也逐渐建立了起来,从最开始的多屏适配方案、基础库、工具链到页面搭建平台和性能体系,最后到客户端融合方案Weex,我随着团队一起经历了业务发展、团队自身成长和行业变革。
与此同时,在我加入阿里巴巴后的这段时间里,随着移动时代的到来,前端也开启了自己的“黄金时代”,它的职责变得更加重要,有了独立的发布权限,技术也变得更加复杂。
一些传统软件开发和互联网服务端的方法论逐步移植到前端开发中,并形成了前端自己的工程体系,诸如持续集成、前后端分离、线上监控……
架构方面,前端架构的任务也从简单的解决兼容和风格问题,逐步过渡到提倡组件化和UI架构模式,最后形成了新一代的前端框架React、Vue和Angular,他们也在竞争和互相学习中成长。
正当处于“黄金时代”的前端技术在全力以赴极速前行之时,我却发现,前端开发者们的步伐似乎渐渐有些跟不上了。
因为在我职业发展的后半段,面试和培养前端工程师已经成为我的长期工作职责。在这期间,我意识到,目前的前端教育几乎是完全缺失的。
在面试应届生过程中,我会习惯性地问表现比较好的同学“你是如何学习前端的”,而我得到的答案多是“自学”“在社团学习”,却从未听到过“在学校学习过”这样的答案。
而对于工作之后的前端开发者来说,没有系统学习的问题仍然存在,常常有一些具有多年从业经验的工程师,仍然会在看到一些用法时惊呼:“还可以这样!”
在我看来,这些用法都是一些基础的不能再基础的知识点,但是他们却浑然不知。
如果深入进去了解,你会发现,表面上看他们可能是一时忘记了,或者之前没注意,但实际上是他们对于前端的知识体系和底层原理没有真正系统地理解。
在阿里工作的时候,我戏称很多同学学前端的方式是“土法学前端”,他们对于知识的理解基本都停留在点上,从来没有大范围把这些点串成线,形成自己的知识体系,因此才会出现上面说的遗漏和盲点。
这个问题在一些一直在小公司工作的前端工程师身上非常突出。
经常能看到一些案例,一些有技术追求、有热情的工程师,因为技术敏感度和主观能动性都不错,所以工作了五六年之后,逐步开始在自己的公司做一些技术管理相关的事情了。
但是,由于他们所在公司的业务并不复杂,也没有技术积累,所以他们自身的技术水平其实并不高,可以说还处于非常初级的阶段(可能面试连阿里P6都过不了)。
做了管理,技术没跟上,并且还错过了最佳的学习时间,这个境遇可想而知,他们在工作中大概率只能是被动地接受需求解决问题,然后也同时焦虑着自己的未来,焦虑着自己的竞争力。
关于前端工程师成长,我认为需要两个视角。一是立足标准,系统性总结和整理前端知识,建立自己的认知和方法论;二是放眼团队,从业务和工程角度思考前端团队的价值和发展需要。只有这样做,才能够持续发展,在高速发展的技术和工程浪潮中稳稳立足。
这也正是“重学前端”这个专栏的初衷,我希望提供一些视角,带你以完备、体系化的方式理解和思考前端的基础知识和工程实践。
除此之外,前端工程师也是开发工程师的一员,除了前端自身的领域知识和工程特点外,你还需要了解程序员通用的编程能力和架构能力。
所以,想要成为优秀的前端工程师,我觉得你需要通过系统地学习和总结获取知识,通过练习获取编程能力,通过工作经验来获取架构和工程能力。
当然,一个为期3个月的专栏无法穷尽前端庞杂的知识,讲知识点也不是我们的目标。知识点讲的再好再全,也不一定能记得住。
我们专栏的目标是帮助你建立自己的知识体系,根据你自己的理解把前端的领域知识链接起来,形成结构,这样做,不但能帮助你记忆知识,还能在其中发现自己知识的缺失,甚至可以凭借知识体系来判断知识的重要性,来决定是否要深入学习。
在这个专栏里,我将知识分成了四个模块来讲解:
前三个模块是前端的基础知识,是个人的前端能力提升,而模块四则是前端团队发展相关的内容,有助于你和团队的整体提高。
在JavaScript部分中,我主要会从文法和运行时的角度去讨论JavaScript语言。它们是互相关联的,而语义就是文法到运行时之间的桥梁;它们分别又是完备的,任何语言特性都离不开两者,所以从语法和运行时的角度,我们都可以了解完整的JavaScript。
CSS和HTML部分,会侧重从语言和设计思想的角度来讲解,我们同样可以对两者的全貌建立一些认知。
浏览器部分,包含了浏览器工作的原理和一些重要的API,包括BOM、DOM、CSSOM和其他一些内容。了解了这些知识,你才能把JavaScript和HTML、CSS连接起来,用JavaScript来实现功能。
前端综合应用部分,主要是我的一些工作经验,我会选择我在手淘和淘宝工作中的一些案例来辅助讲解。
前面,我说到前端是一个非常年轻的职业,但我仍然认为前端具有很多空间和机会,一些基础设施仍然简陋,前端的能力可以带来更多的业务场景,这些有待于我们去发掘。
前端社区非常活跃,新技术也在不断出现。在这样的环境下,机会和竞争并存,学习也犹如逆水行舟,不进则退,建立自己的知识体系和方法论,你才能够保持领先优势。
我希望从我的经验出发,给你一些启发和帮助,并借由这个专栏帮你建立自己的前端知识体系。同时,我也相信,在你们中间一定会产生更多能够带领前端领域取得突破的、优秀的前端工程师。
在你的认识中,前端知识的结构是怎样的?欢迎留言告诉我,我们一起讨论。
在任何时代,
教育说起来都是一件高大上的事,
但却没有什么真正有价值的东西是教得会的,
没有任何一种文化模因
可以说清楚一个个体的全部问题。
在任何时代,
想要抓住人性的弱点来赚钱都非常容易,
没有一点高级。
相反,想要建设一种文化,
耐心地拆除信息壁垒,
并且能够坚持下来,
那真不是一般的不易。
在任何时代,
在一秒钟内看到本质的人,
和花半辈子看不清的人,
自然是不一样的命运。