forked from phodal/fe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
executable file
·354 lines (349 loc) · 48.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>我的职业是前端工程师 – </title>
<style type="text/css">code{white-space: pre;}</style>
<link rel="stylesheet" href="style.css">
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
<meta name="viewport" content="width=device-width">
</head>
<body>
<h1>我的职业是前端工程师</h1>
<p>By <a href="https://www.phodal.com/">Phodal</a> (Follow Me: <a href="http://weibo.com/phodal">微博</a>、<a href="https://www.zhihu.com/people/phodal">知乎</a>、<a href="https://segmentfault.com/u/phodal">SegmentFault</a>)
</p>
<p>我的其他电子书:</p>
<ul>
<li>《<a href="https://github.com/phodal/ideabook">Phodal's Idea实战指南</a>》</li>
<li>《<a href="https://github.com/phodal/designiot">一步步搭建物联网系统</a>》</li>
<li>《<a href="https://github.com/phodal/github-roam">GitHub 漫游指南</a>》</li>
<li>《<a href="https://github.com/phodal/repractise">RePractise</a>》</li>
<li>《<a href="https://github.com/phodal/growth-ebook">Growth: 全栈增长工程师指南</a>》</li>
<li>《<a href="https://github.com/phodal/growth-in-action">Growth: 全栈增长工程师实战</a>》</li>
</ul>
<p>微信公众号</p>
<p><img src="http://articles.phodal.com/qrcode.jpg" alt=""/></p>
<p>
当前为预览版,在使用的过程中遇到任何遇到请及时与我联系。阅读过程中问题,不烦在GitHub上提出来:
<a href="https://github.com/phodal/fe/issues">Issues</a>
</p>
<p>
阅读过程中遇到语法错误、拼写错误、技术错误等等,不烦来个Pull Request,这样可以帮助到其他阅读这本电子书的童鞋。
</p>
<div style="width:800px">
<iframe src="http://ghbtns.com/github-btn.html?user=phodal&repo=fe&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe>
</div>
<nav id="TOC">
<ul>
<li><a href="#我的职业是前端工程师我要成为一个前端设计师">我的职业是前端工程师:我要成为一个前端设计师</a><ul>
<li><a href="#漂亮的前台">漂亮的前台</a></li>
<li><a href="#我要成为一个前端设计师">我要成为一个前端设计师</a></li>
<li><a href="#关于我的职业是前端工程师">关于《我的职业是前端工程师》</a></li>
</ul></li>
<li><a href="#我的职业是前端工程师入门不是应该很简单吗">我的职业是前端工程师:入门不是应该很简单吗?</a><ul>
<li><a href="#前端之路">前端之路</a></li>
<li><a href="#我的前端入门">我的前端入门</a><ul>
<li><a href="#我的第一个网站">我的第一个网站</a></li>
<li><a href="#copypaste-from-cookbook">Copy/Paste from Cookbook</a></li>
<li><a href="#开发工具">开发工具</a></li>
<li><a href="#jquery-是最好用的">jQuery 是最好用的</a></li>
</ul></li>
</ul></li>
<li><a href="#学习前端只需要三个月语言篇">学习前端只需要三个月【语言篇】</a><ul>
<li><a href="#javascript-语言的变化">JavaScript 语言的变化</a><ul>
<li><a href="#javascript">JavaScript</a></li>
<li><a href="#es6">ES6+</a></li>
<li><a href="#typescript">TypeScript</a></li>
</ul></li>
<li><a href="#小结">小结</a></li>
</ul></li>
<li><a href="#如何选择合适的前端框架告别选择恐惧症">如何选择合适的前端框架,告别选择恐惧症</a><ul>
<li><a href="#前端的选择恐惧症">前端的选择恐惧症</a><ul>
<li><a href="#技术选型不仅仅受技术影响">技术选型:不仅仅受技术影响</a></li>
<li><a href="#上线时间影响框架">上线时间影响框架</a></li>
<li><a href="#锤子定律你需要更大的视野">锤子定律:你需要更大的视野</a></li>
</ul></li>
<li><a href="#前端框架一览">前端框架一览</a><ul>
<li><a href="#jquery-使用生态解决问题">jQuery, 使用生态解决问题</a></li>
<li><a href="#backbone.js脊椎连接框架">Backbone.js,脊椎连接框架</a></li>
<li><a href="#angular一站式提高生产力">Angular,一站式提高生产力</a></li>
<li><a href="#react组件化提高复用">React,组件化提高复用</a></li>
<li><a href="#vue.js简单也是提高效率">Vue.js,简单也是提高效率</a></li>
<li><a href="#小结-1">小结</a></li>
</ul></li>
<li><a href="#总结">总结</a></li>
</ul></li>
<li><a href="#前端基础知识">前端基础知识</a><ul>
<li><a href="#准备工作">准备工作</a></li>
<li><a href="#编写一个简单的-html">编写一个简单的 HTML</a></li>
<li><a href="#漂亮的-css">漂亮的 CSS</a></li>
<li><a href="#javascript-居然是小三">JavaScript 居然是小三</a></li>
</ul></li>
</ul>
</nav>
<h1 id="我的职业是前端工程师我要成为一个前端设计师">我的职业是前端工程师:我要成为一个前端设计师</h1>
<blockquote>
<p>我年轻的时候,是一个前端工程师。那时候,有这样一个传说:美工是最受妹子的欢迎,其次是半个美工的前端工程师。</p>
</blockquote>
<p>本故事纯属瞎掰,如有雷同纯属巧合——Phodal <span class="citation" data-cites="PasteRight">@PasteRight</span></p>
<p>未满 18 年时,想成为一名 Kernel Hacker,就是那种操着键盘,在屏幕洒下一行行汇编语言的大牛。在我学了一段时间 C++ 后,我觉得:『用记事本写代码,并运行起来』的故事都是骗人的。为了将代码转变为程序,你还需要一个编译工具。</p>
<p>然而有一天,我在网吧里看到一个人在记事本里写代码。开始的时候,我觉得这个人是个新手吧,怎么拿记事本在写代码呢,不是应该都拿 IDE 才能编译运行吗?几分钟过后,我发现他居然能将,记事本写的程序运行起来,太神奇了,Amazing Man。</p>
<p>后来,为了在别人面前装这个 100 分的逼,我成了一名 Web 工程师,而且还是一个前端工程师。</p>
<p>(PS:以上纯属瞎扯)</p>
<h2 id="漂亮的前台">漂亮的前台</h2>
<p>各位看官中,有些可能不是前端工程师,那就先让我来说说前端工程师是干什么。前端又可以称之为前台,不是那种每天对你笑、帮你开门、长得还算不错的前台,然而却也差不了多少。</p>
<p>他们要做出好看的、美丽大方的界面,以免吓走那些对颜值有要求的挑剔客户;还要对指引好用户,免得有些用户认错了楼、走错了路口,然后再也不来光顾你们的网站了;有些时候,还要像处女座纠结于对齐,纠结于 px px 的程序员。</p>
<p>你还会看到他们拿起纸当尺子,一点点的测量着什么东西,好似在怀疑这个屏幕是不是真的是 15.4 寸。 如果你看到一个程序员,他在纠结椅子是不是摆放正确的,那么它有可能是三种程序员中的一种:处女座程序员、前端工程师,还有测试工程师。</p>
<p>我们就像上个世纪的网民,时不时地按下 F5 又或者 Command + R 来刷新页面,一直在怀疑页面上的内容是不是最新的。好在后来,有一个伟大的大魔法师发明了一个工具,可以检测到代码修改,自动地帮你刷新页面。终于,不再像个老大爷一样踢电脑,以指望提高图片的质量,甚至去掉马赛克。</p>
<p>过去,我也无法理解:这群智力超群的程序员,为什么会变得如此px px 计较,直到我成为了其中的一员。</p>
<h2 id="我要成为一个前端设计师">我要成为一个前端设计师</h2>
<p>习惯了大学的生活过后,我和好友楚非就一起去租了一个服务器,从此生活就变得有点艰难。不过有了一个服务器,我们就可以去做个网站,并托管别人的网站,然后就可以坐在学校里数钱了。对于当时的我而言,我并不想成为一个 Web 开发工程师,我还是从心底向往底层的开发。</p>
<p>理想很美好,现实很残酷。虽然我们有了一个服务器,但是它不能立刻地为我们赚钱。我不知道一个完整的网站是怎样的,也没有找到客户。后来,直到大二下学期快结束的时候,我们才算迎来真正的客户。在那段找不到客户,也没有能力找客户的日子里,我们就这样把自己逼上了一条不归路。</p>
<blockquote>
<p>就这样和很多人一样,为了赚钱,就这样成为了一个前端工程师。</p>
</blockquote>
<p>这时,我们就遇到了一个问题:我们俩究竟谁做前端,谁做后台?</p>
<p>这结局大多数人都是知道的,我来负责前端。然而每每说到:他是学美术的,他去做后台;而我是学电子信息工程的,我来负责前端,总会有人感到一些惊讶。选择前端,有这么一个主要的原因:<strong>离成为设计师的目标更进一步</strong>。</p>
<p>我所理解的“设计师”,是广泛意义上的设计师。他们做一些创意的工作,以此来创造一些令人啧啧称赞的作品。这些作品不仅仅可以是一件雕塑,一幅画,还能是一个 Idea,一段代码。</p>
<p><strong>当你是一个前端工程师的时候,你是一个程序员,还是一个设计师。</strong></p>
<p>程序员本身也是设计师。虽然程序已经代替了相当数量的手工操作,要想代替程序员则需要更多的时日。然而,程序员手艺的好坏是有相当大的差异的。初学编程的时候,总会看到各种“程序设计”这样高大上的字眼,设计才是程序的核心。这就意味着,写代码的时候,就是在设计作品。设计是一门脑力活,也是一门模式活,从中能看出一个人的风格,从而了解一个人的水平。</p>
<p>因为我认为,前端工程师还应该懂得设计。我便花费了很多时间去:学习素描,熟悉一些原型设计软件,了解各种配色原理。以指望我可以像一个设计师一样,做好前端网页的设计。毕竟代码和大部分艺术作品一样,容易被临摹、复制,而要复制思想则不是一件容易的事。</p>
<p>而到了今天,我的设计能力还是有待商榷。幸运的是,我可以熟练地使用各种可视化工具,然后做出各种美妙的图案。</p>
<p>我还能写编写一行行的前端代码,并写下这个系列(《我的职业是前端工程师》)的文章,来帮助大家深入了解前端工程师。</p>
<h2 id="关于我的职业是前端工程师">关于《我的职业是前端工程师》</h2>
<p>人啊,总是喜欢写点东西去纪念自己的功绩,我也不例外。当我写了一段有意思的代码、尝试了一个新的框架、解决了一个很久的 Bug,我总会写个博客来炫耀一下。后来,随着博客越写越多,我开始尝试的整理一些话题,并将其编成电子书放在 GitHub 上共享。后来,就慢慢地有了出版第一本书的机会,想来第二本书也是能出版的,也应该很快地就会出版的。</p>
<p>我的第一本书是纪念大学的专业,电子学习的是电子信息工程,便写了一本物联网相关的书籍。第二本则是一本关于全栈书籍,想来我在前后端之间已经受过很多苦,也因此学了很多知识,这些知识对于我来说像是一种财富。虽然花费了相当多的时间在编写上,但是总体上来说,对于我的益处还是大于弊处的。为了保证内容的准确性,一遍又一遍地去梳理知识体系,不得不再次去翻阅放在书架的书籍。也因此算是印证了那句话:输出是最好的输入。</p>
<p>前端是一个很有趣的领域,有太多的知识点,和不同的领域都有所交集。为了展示前端的广度,只能像散文一样展开不同的知识点。因此呢,这一系列的文章,不再像过去的电子书一样,有着连贯的、互相依赖的知识。</p>
<p>我真正开始从事前端这个职业,算了一下也差不多是三年了。三年之前的学校三年里,我在努力地成长为前端工程师,成为全栈工程师。而工作的这三年里,正好是前端高速发展的三年,他的发展速度有些夸张。落后了三个月,你就有可能需要重新入门前端了,痛苦的往事。</p>
<h1 id="我的职业是前端工程师入门不是应该很简单吗">我的职业是前端工程师:入门不是应该很简单吗?</h1>
<p>入门前端,是一件很难的事吗?在今天,我也没有想好一个答案,也不知道怎样给出一个答案。这个问题并不取决于前端,而是取决于不同人的需求。到底是想要快得一步登天呢,还是一点点的慢慢来,去享受前端带来的乐趣。</p>
<p>对于不同领域的学者来说,都会有一个相似的问题:如何从入门到精通?入门并不是一件很复杂的事,只是多数人想要的是<strong>更快的入门</strong>,这才是真正复杂的地方。虽说条条道路都是通过罗马的,但并不是每条道路都是能满足人们要求的。对于 A 说的路线并不一定适合于 A ,有可能会适合于 B;适合于 B 的路线,也有可能只适合于 B。</p>
<h2 id="前端之路">前端之路</h2>
<p>谈起路线规则这事,就会联想起算法里的路径问题。想了想,发觉“如何教人入门前端”与“选择合适的路径”颇为相似的,要实现这样的规划蛮难的。先上张图,加深一下印象:</p>
<figure>
<img src="images/short-path.jpg" alt="最短路径" /><figcaption>最短路径</figcaption>
</figure>
<p>接着,我们来思考这样的一个问题:</p>
<blockquote>
<p>每个初学者都处于“1”,最后的目标都是到“9”,那么你会怎么帮助他们规划路线?</p>
</blockquote>
<p>假设,每一个数字都对应了技术栈,并标注了每个技术栈学习所需要的时间。那么,这时要计算出<strong>最快的学习路线</strong>也就容易了。而这种开挂的感觉,就像是我们拥有了游戏中的技能树的一样。技能树上,包含了所有已知的技能,以及:学习某个技能所需要的时间,学习某个技能后可以触发某个技能等等。</p>
<figure>
<img src="images/sherlock.jpg" alt="技能树" /><figcaption>技能树</figcaption>
</figure>
<p>不幸的事,这个路线不可能会怎么简单。倘若你是一个在校的学生,或者是相似的研究人员,那么这种路线也颇为适合。理想的情况下,我们可以自由地分配自己的时间,在对应的技术栈上花费相应的时间。这就好像是游戏世界的技能树一样,我们所拥有的点数是固定的,那么所能学习的技能也是固定的。</p>
<p>假使真实世界的前端技能树已经很清晰,那么这里的点数对应的就是时间。在时间固定的情况下,我们所能学习的技能也是固定的。而技能树中的时间花费是一个大的问题:当我们学习完某个技能后,我们可能就拥有其他技能的加成。</p>
<p>在已经学会了 ES6 的情况下,学习 TypeScript 就变得更轻松,这时学习 TypeScript 的时间就会更短。也因此,相似的技术栈可以归类到一起。遗憾的是,学习相似的技术栈仍然是需要时间的。</p>
<p>回到前端技术的话题上,在编写复杂前端应用时,我们都会采用前端框架来加快开发。前端框架的技术基础都是一样的,有区别的是,它们衍生出来的技术思想。有的框架创造出了一些有意思的 DSL(领域特定语言),可以借此编写出独立于语言的代码,这些代码也可以用在不同的领域里。</p>
<p>一个很有意思的例子就是 Mustache 模板,即可以让我们用后台语言,如 Java,来渲染 Mustache 模板为 HTML,又可以在前端里使用 Mustache.js 来将模板渲染为 HTML。相似的,对于 React 中的 JSX 也是如此,我们即可以用 Node.js 与 React 在后台来渲染出页面,又可以在前端来渲染 JSX 为 HTML。</p>
<figure>
<img src="images/fe-path.png" alt="简单的前端学习路径" /><figcaption>简单的前端学习路径</figcaption>
</figure>
<h2 id="我的前端入门">我的前端入门</h2>
<p>在我刚学前端工程师的时候,由于只需要编写 CSS、JavaScript 和 HTML,因此要做前端的活相当的简单。有时,甚至会觉得有些乏味。</p>
<h3 id="我的第一个网站">我的第一个网站</h3>
<p>大一时,年轻气盛就去办了个社团,当了个社长。那会儿还能使用各种 Google 的服务,Google 刚刚开始推广它的云服务 Google App Engine。用户只需要点击一个按钮,就可以上传代码,应用就会自动地部署到相应的网站上了。下图就是我的第一个网站:</p>
<figure>
<img src="images/django_gae.jpg" alt="Django GAE" /><figcaption>Django GAE</figcaption>
</figure>
<p>当时,写给客户的代码大多乏味,没有挑战性。为了尝试各种新特性,我就将各种奇怪的 CSS3 加到其中。</p>
<p>这一点在今天的日常工作里,也没有太多的变化。工作写代码是为了活下去,业余写代码则是为了兴趣。有意识地将两者分开,才能使技术更好的成长。我们不会因为,在项目里引入新技术而沮丧。同时,在业余时自由的使用新的技术,来提升自己的技术与视野。</p>
<p>后来,世道变了,免费的东西还能使用,但是网站已经访问不了。我们尝试很 SAE 上迁移,虽然 SAE 很不错,但是你是要去备案的。再后来,我们就去租用自己的服务器了。</p>
<h3 id="copypaste-from-cookbook">Copy/Paste from Cookbook</h3>
<p>与现在稍有不同的是,现在写代码是 Copy/Paste from StackOverflow,那时写代码是 Copy/Paste from Cookbook。所以,我们只需要三本书就足够了:</p>
<ul>
<li>CSS Cookbook</li>
<li>JavaScript Cookbook</li>
<li>jQuery Cookbook</li>
</ul>
<p>它们包含了我所需要的一切,对应于不同的功能,都有对应的代码。我们所需要做的就是<strong>在合适的地方放上合适的代码</strong>。</p>
<p>在阅读了大量的书后,我才得到了上面的结论。不过,大学不像现在这么“宽裕”,不能轻松地去买自己想看的书。一本书抵得上好几天的饭钱,不会毫不犹豫地“一键下单”。现在,仍然会稍微犹豫一下,这主要是房价太贵,租的房子太小。尽管我们的学校是一所二本院校,但是图书馆还算是不小的——虽然没有啥各种外语书,但是大部分领域的书总算是有一两本的,每个月还会进一些新书——反正屈指可数。四年下来,我算是能知道每一本计算机书的大概位置。</p>
<p>因此,如果你只是想为了完成任务,而去完成任务。你就会发现,编程是相当无聊的,和一般的工作无异。</p>
<h3 id="开发工具">开发工具</h3>
<p>最初,我颇为喜欢 Adobe DreamWeaver,还有 Chrome 浏览器,它们结合起来能完成大部分的 UI 工作。</p>
<p>尽管在今天看来,DreamWeaver 是个一个奇怪的工具,它可以让我们拖拽来生成代码,但是这些生成的代码都是臭不可闻的。但是我爱及了他的及时预览地功能了,特别是当我在编写 CSS 的时候,不再需要在浏览器、开发工具不断切换。</p>
<p>慢慢地,当我开始越来越多的使用 JavaScript 时,DreamWeaver 提供的功能就变得越来越有限了,我开始觉得它越来越难用了。曾经有一段时间里,我使用 Aptana——它可以将 minify 后的代码格式化。</p>
<p>现在,我使用 Intellij IDEA 和 WebStorm作为主要开发工具,它们的<strong>重构功能</strong>让我难以自拔。当我需要修改一些简单的文本时,我就会使用 Vim 或者 Sublime text。在命令行里发现了一个问题,直接可用命令行来打开并修改。</p>
<p>Chrome 浏览器在当时虽然很不错,但是当时市场占有率太低。只能拿它来作平时的浏览器,看看各种 IE 上的 Bug,再玩 CSS3、HTML 5 等等各种特效。多数时候你还是要用 IE 的,写下一行行的 CSS Hack,以确保大部分的用户是可以正常使用的。</p>
<p>今天,也仍然在使用 Chrome 作为我的日常和开发用浏览器。虽然它还没有解释臭名昭著的内存问题,但是我们已经离不开它的 Console,Device Toolbar 等等的功能,同时还有运行在这上面的各种插件,如 Postman,PageSpeed 等等。</p>
<h3 id="jquery-是最好用的">jQuery 是最好用的</h3>
<p>在我发现了 jQuery 之后,我才知道它是一个神器。jQuery 有一个庞大的生态系统,有一系列丰富的插件。我们所需要做的就是,知道我们要实现的功能,找到相应的插件。紧接着,就去 Google 有相应的插件,然后按照他的 README 写下来即可。即使没有的插件,我们也可以很容易的编写之。</p>
<p>到了后来,我觉得前端甚是无聊。这主要是限制于我们接的一些业务,都是企事业单位的单子,每天都是无尽的 IE 的兼容问题。这让我觉得同时使用很多个 IE 版本的 IETester,是一个伟大的软件。</p>
<p>过了那段时间后,看到了 Node.js、Backbone、React、Angular 打开了另外一个世界,这算是前端 3.0 的世界了。</p>
<h1 id="学习前端只需要三个月语言篇">学习前端只需要三个月【语言篇】</h1>
<blockquote>
<p>过去,我一直无法相信:一个新人在三个月里可以学好前端。后来,我信了。因为三个月后,我又是一个前端的新人,我又需要重新入门前端。</p>
</blockquote>
<p>前端领域好似也有一个“摩尔定律”。戈登·摩尔提出来:<strong>积体电路上可容纳的电晶体(晶体管)数目,约每隔24个月便会增加一倍</strong>,后来经常被引用的“18个月”。而对于前端领域来说,每隔 3-6 个月,<strong>知识点将增加一倍</strong>。</p>
<p>过去一年(即 2016 年)的每三个月(或者半年)里,前端领域不断涌现出新的知识,这些新的知识不断地在更新。这些知识点,可以源自于后台知识领域,源自于某些特定的语言,源自于新的知识理念。我们可以很轻松地找到一个例子,如前端所需要的 JavaScript 语言本身,这个语言出现了越来越多的变种。</p>
<p>为了完成一个复杂的前端应用,我们需要编写大量的 JavaScript 代码。但是早期版本的 JavaScript,并不适合编写中大规模的前端工程。</p>
<h2 id="javascript-语言的变化">JavaScript 语言的变化</h2>
<p>几年间,出现了 CoffeeScript、TypeScript、ClojureScript、Dart、ES6 等等的语言,他们都可以编译为 JavaScript,随后就可以在浏览器上运行。诸如 ES6,这一个新的 JavaScript 版本(现有的 JavaScript 版本,称为 ES5,即 EcmaScritp 5),则可以在最新的浏览器上运行部分或者全部的特性。</p>
<p>这些语言在不同的时间段里,所受到的受关注程度都是不一样的。它们都是各自的特色,在不同的时期所到的欢迎程度也是不一样的:</p>
<figure>
<img src="images/js-language-compare.jpg" alt="JavaScript编译语言" /><figcaption>JavaScript编译语言</figcaption>
</figure>
<p>这种变化相当有趣。尽管 JavaScript 是所有主流浏览器上唯一支持的脚本语言,但是它在过去的主要用途是用来:做一些页面“特效”。它可以通过 DOM API 来操作页面上的元素,而这些元素就是显示在页面上的内容。</p>
<p>随后 Ajax 技术诞生了,开发人员发现可以用 JavaScript 做更多的事。JavaScript 之时,是用于在客户端上执行一些指令。而 Ajax 则可以让浏览器直接与服务端通讯。这就意味着,<strong>你可以在浏览器间接地去操作数据库</strong>,前端应用便因此而变得更加庞大。</p>
<h3 id="javascript">JavaScript</h3>
<p>最初,JavaScript 是由 Netscape 雇佣 Brendan Eich 来开发的。当时他花了 10 天时间,设计出了这个语言的第一个版本。Netscape 与 Sun公司合作开发了该语言,当时 Java 语言比较火热,也因此该语言由 LiveScript 改名为 JavaScript。由设计初衷就是,<strong>适合于新手来使用</strong>。</p>
<p>此时正值浏览器大战之时,微软也推出了与 JavaScript 相似的 JScript 语言,并且内置于 IE 3.0 中。随后 IE 借助于 Windows 的威力,逐渐地占领了市场。后来,Netscape 便将 JavaScript 提交给欧洲计算机制造商协会进行标准化。标准化后的 JavaScript 便称为 ECMAScript,JavaScript 的版本也以 ECMAScript 来命名。</p>
<p>尽管 JavaScript 的标准由 ECMA TC39<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a> 委员会制定,但是要操作浏览器的元素,还需要 DOM(Document Object Model,文档对象模型)。而 DOM 是由 W3C 组织推荐的处理 XML 的标准编程接口。遗憾的是,不同浏览器对于 DOM 的支持并不一致,还存在一定的差异。在早期的浏览器里,对于 DOM、事件、Ajax 的支持存在一定的差异,因此像 jQuery 这种跨浏览器的 JavaScript 库,相当的受欢迎。</p>
<p>然而,为了新手更容易上手,该语言缺少一些关键的功能,如类、模块、类型等等。在一些完备的 Web 框架里,框架本身会拥有相应的功能。</p>
<p>这些问题可以由各式各样的 JavaScript 库来解决。</p>
<ul>
<li>我们需要<strong>类的功能</strong>时,可以用 klass 库来补充;</li>
<li>我们需要<strong>依赖管理</strong>时,可以用 Require.js 库来补充;</li>
<li>我们需要<strong>类型检查</strong>时,可以用 tcomb 库来补充;</li>
<li>我们需要<strong>Promise 库来解决 callback hell</strong>时,可以用 Bluebird 来补充。</li>
<li>。。。</li>
</ul>
<p>这一切看上去都很完美,但是好像有一点不对劲。</p>
<p>这些功能明明是这个语言应该要有的。我们却要在一个又一个的项目里,引用这些<strong>本不需要</strong>引用的库。</p>
<h3 id="es6">ES6+</h3>
<p><strong>作为一个程序员,如果我们觉得一个工具不顺手,那么应该造一个新的轮子</strong>。我也喜欢去造前端的轮子,有时候是为了理解一个框架的原理,有时候则是为了创建一个更好的工具。也因此,当 JavaScript 不能满足前端工程师需求的时候,我们应该发展出一个更好的语言。于是,ES 6 就这样诞生了。</p>
<p>继上面的 JavaScript 的发展历史,现在主流浏览器都支持 ECMAScript 5.0 版本的标准,并且部分浏览器可以支持 ECMAScript 6。随后,ECMA 的草案以年份来命名,如 2016 年发布的 ECMAScript 草案称之为 ECMAScript 2016。而 ES 6 则对应于 ES 2015。</p>
<p>于是,现在:</p>
<ul>
<li>你可以使用定义函数的<code>默认参数</code>。不再需要使用 option,并 merge 这个对象了。</li>
<li>你可以使用模板对象,使用形如<code>`$ {NAME}`</code>的形式来拼接模板。不再需要在一个变量切换单引号 ’ 和双引号 “,并使用很多加号 + 。</li>
<li>你可以使用箭头函数,来减少回调的代码量,并改善作用域 this 的问题。</li>
<li>你可以使用原生的 Promises 来解决地狱式回调的问题。</li>
<li>你还可以在 JavaScript 中使用真正的面向对象编程。</li>
<li>。。。</li>
</ul>
<p>在最新的 Chrome、Edge、Safari、Firefox 浏览器里,它们对于 ES6 的特性支持几乎都在 90% 以上。当我们需要在浏览器上运行 ES6 代码时,就需要使用类似于 Babel 这样的转译工具,来将代码转换为 ES5 来在普通浏览器上运行。</p>
<p>遗憾的是,主流的浏览器对于 ES2016+ 以及下一代的 ES.next 的支持是有限的。除此,它还有一系列需改进的语法,并不能让我觉得满意。</p>
<p>然后,我开始转向了 TypeScript。</p>
<h3 id="typescript">TypeScript</h3>
<p>我开始尝试 TypeScript 的原因是,ES6 一直在变化。在 ES6 语言特性没有稳定下来的时候,我选择它作为技术栈总会存在一些风险。在这个时候,TypeScript 就成为了一个更好的选择——它创建得更早,并且语言特性稳定。而真正促使我使用 TypeScript 的契机则是,Angular 2 中采用了 TypeScript 作为开发语言。简单的来说,就是我需要用它,所以我才学 TypeScript 的。</p>
<p>TypeScript 与其他编译为 JavaScript 的语言初衷是类似的,为了开发大规模 JavaScript 的应用。TypeScript 是 JavaScript 的严格超集,任何现有的JavaScript程序都是合法的TypeScript程序。TypeScript 第一次对外发布是在 2012 年 10 月,而在那之前在微软的内部已经开发了两年。因此,我们可以认为它是在 2010 年左右开始开发的。</p>
<p>与同时期的 ES6 相比,它更加完善,并且更适合于大型应用开发。TypeScript 从其名字来看,就是 Type + Script,它是一个强类型的语言。而 ES6 只带有类型检查器,它无法保证类型是正确的。这一点在处理数据 API 时,显得非常具有优势。当接口发生一些变化时,这些 interface 就会告诉你哪些地方发生了变化。</p>
<p>并且未来 TypeScript 将会和 ECMAScript 建议的标准看齐。</p>
<h2 id="小结">小结</h2>
<p>除去语言本身,还有各种新的前端框架带来的变化。和其他领域(如后台,APP等等)中的框架一样,有的框架可以用于开发中大型应用,有的框架则能让我们更好地完成开发。</p>
<h1 id="如何选择合适的前端框架告别选择恐惧症">如何选择合适的前端框架,告别选择恐惧症</h1>
<blockquote>
<p>将 package.json 中的 Ionic 版本改为 2.0.0 的时候,我就思考一个问题。这个该死的问题是——我到底要用哪个框架继续工作下去。</p>
</blockquote>
<p>刚开始学习前端的时候,SPA(单页面应用)还没有现在这么流行,可以选择的框架也很少。而今天,我随便打开一个技术相关的网站、应用,只需要简单的看几页,就可以看到丰富的<strong>前端框架世界</strong> Angular 2、React、Vue.js、Ember.js。</p>
<p>当我还是一个新手程序员,我从不考虑技术选型的问题。因为不需要做技术选型、不需要更换架构的时候,便觉得框架丰富就让它丰富吧,<strong>反正我还是用现在的技术栈</strong>。等到真正需要用的时候,依靠之前的基础知识,我仍能很轻松地上手。</p>
<p>可是一旦需要考虑选型的时候,真觉得天仿佛是要塌下来一般。选择 A 框架,则使用过 B 框架的可能会有些不满。选用 B 框架,则使用 A 框架的人会有些不满。选择一个过时的框架,则大部分的人都会不满。这点“小事”,也足够让你几天几夜睡不了一个好觉。</p>
<h2 id="前端的选择恐惧症">前端的选择恐惧症</h2>
<p>年轻的程序员都是好奇的猫,玩过一个又一个的前端框架。从毛球上弄出一条条的线,玩啊玩,最后这一个个的框架在脑子里搅浆糊。</p>
<h3 id="技术选型不仅仅受技术影响">技术选型:不仅仅受技术影响</h3>
<p>有太多的选择,就是一件麻烦的事;没有选择时,就是一件更麻烦的事;有唯一的选择时,事情就会变得超级简单。</p>
<p>倘若,我是那个使用 Java 来开发 API 的少年,我会使用 Spring Boot 来作为开发框架。尽管 Java 是一门臃肿的语言,但保守的选择不会犯上大错。</p>
<p>倘若,我是那个使用 Python 来开发 Web 应用的少年,我会使用 Django 来作为开发框架。它可以让我快速地开发出一个应用。</p>
<p>只可惜,我不再是一个后台开发者,我不再像过去,可以直接、没有顾虑的选择。当我选择 JavaScript 时,我就犯上了「选择恐惧症」。技术选型也是没有银弹的——没有一个框架能解决所有的问题。</p>
<p>在《Growth:全栈 Web 开发思想》一书中,我曾提到过影响技术选型的几个因素。</p>
<figure>
<img src="images/tech-decide.png" alt="技术选择因素" /><figcaption>技术选择因素</figcaption>
</figure>
<p>这时,为了更好的考量不同的因素,你就需要列出重要的象限,如<strong>开发效率</strong>、团队喜好等等。并依此来决定,哪个框架更适合当前的团队和项目。</p>
<figure>
<img src="images/pri.jpg" alt="PRI" /><figcaption>PRI</figcaption>
</figure>
<p>即使,不考虑前端框架以外的因素,那么技术选型也是相当痛苦的一件事。</p>
<h3 id="上线时间影响框架">上线时间影响框架</h3>
<p>每一个框架从诞生到受欢迎,都有其特定的原因和背景。不同的开发者选择时,也是依据于其特定情景下的原因和背景。</p>
<p>如 Ruby On Rails诞生之时,带来了极大的开发效率,而开发效率正是当时大部分人的痛点。我们知道 Ruby On Rails 是一个大而广的框架,它可以提供开发者所需要的一切,开发者所需要做的就是实现业务代码。当开发效率不再是问题时,自由度变成了一些开发者的痛点,此时像 Sinatra 这样的微框架就受这些人欢迎。</p>
<p>也因此,开发效率会在很大程度上影响技术选型。毕竟,开发效率在很大程度上决定了上线时间,上线时间很大地影响了技术选型。</p>
<ul>
<li>用几星期的时间来做一个网站,我首先想到的会是找一个模板。</li>
<li>用几个月的时候来做一个网站,我仍然会想到找一个框架。</li>
<li>用几个年的时间来做一个网站,我会想着是不是可以造几个轮子。</li>
</ul>
<p>遗憾的是,要遇到可以造轮子的项目不多。</p>
<h3 id="锤子定律你需要更大的视野">锤子定律:你需要更大的视野</h3>
<p><strong>年轻的时候,学会了 A 框架,总觉得 Z 网站用 A 框架来实现会更好</strong>,一定不会像今天这样经常崩溃、出Bug。**时间一长,有时候就会发现,Z 网站使用 A 不合适,他们的问题并不是框架的问题,而是运维的问题。</p>
<p>后来,出于对职业发展的探索,我开始了解咨询师,看到一本名为《咨询的奥秘》的书籍。在这其中,提到一个有意思的定律“锤子定律”(又称为工具定律)——<strong>圣诞节收到一把锤子的孩子,会发现所有东西都需要敲打</strong>。 出现这种情况的主要原因是,<strong>开发者对一个熟悉的工具过度的依赖</strong>。</p>
<p>认真观察,就会发现这个现象随处可见。当一个新手程序员学会了某个最新的框架,通常来说这个框架有着更多的优点,这个时候最容易出现的想法是:<strong>替换现有的框架</strong>。可是,现有的框架并没有什么大的问题。并且凭估不充分时,新的框架则存在更多的风险。</p>
<p>并且,对于某个熟悉工具的过度依赖,特别容易影响到技术决策——看不到更多的可能性。这时候,我们就需要头脑风暴。但是这种情况下,头脑风暴很难帮助解决问题。</p>
<p>在这个时候,拥有更多项目、框架经验的人,可能会做出更好的选择。</p>
<h2 id="前端框架一览">前端框架一览</h2>
<p>在这个复杂的前端框架世界里,我不敢自称是有丰富的徒刑经验。我只能去分享我用过的那些框架,读者们再结合其他不同的框架来做决定。</p>
<h3 id="jquery-使用生态解决问题">jQuery, 使用生态解决问题</h3>
<p>jQuery 创立之初的主要目标是,简化 HTML 与 JavaScript 之间的操作,开发者可以轻松地使用 <code>$('elment').doSomething()</code> 的形式来对元素进行操作。诞生之后,由于其简单容易手、并且拥有丰富的插件,几度成为最受欢迎的前端框架。大部分动态交互效果,都能轻松地找到 jQuery 插件。即使,没有也能通过其 API,快速地编写相应的插件。</p>
<p>在很多人看来,jQuery 似乎是一个不会在未来用到的框架。可惜到了今天(2017年),我仍然还在项目中使用 jQuery 框架。一年前,我们仍在一个流量巨大的搜索网站上使用用 jQuery。在这几个项目上,仍然使用 jQuery 的原因,大抵有:</p>
<ul>
<li>项目功能比较简单。并不需要做成一个<strong>单页面应用</strong>,就不需要 MV* 框架</li>
<li>项目是一个<strong>遗留系统</strong>。与其使用其他框架来替换,不如留着以后重写项目</li>
</ul>
<p>所以,在互联网上仍有大量的网站在使用 jQuery。这些网站多数是 CMS(内容管理系统)、学校网站、政府机构的网站等等。对于这些以内容为主的网站来说,他们并不需要更好的用户体验,只需要能正确的显示内容即可。</p>
<p>因此即使在今天,对于一般的 Web 应用来说,JavaScript 搭配 jQuery 生态下的插件就够用。然而,对于一些为用户提供服务的网站来说,前端就不是那么简单。</p>
<h3 id="backbone.js脊椎连接框架">Backbone.js,脊椎连接框架</h3>
<p>从 Ajax 出现的那时候开始,前端便迎来了一个新的天地。后来,智能手机开始流行开来。Web 便从桌面端往移动端发展,越来越多的公司开始制作移动应用(APP 和 移动网站)。jQuery Mobile 也诞生这个特殊的时候,然而开发起中大型应用就有些吃力。随后就诞生了 Backbone、Angular 等等的一系列框架。</p>
<p>毕竟,<strong>作为一个程序员,如果我们觉得一个工具不顺手,那么应该造一个新的轮子。</strong></p>
<p>Backbone.js 是一个轻量级的前端框架,其编程范型大致上匹配MVC架构。它为应用程序提供了模型(models)、集合(collections)、视图(views)的结构。</p>
<p>Backbone 的神奇之处在于,在可以结合不同的框架在一起使用。就像脊椎一样,连接上身体的各个部分。使用 Require.js 来管理依赖;使用 jQuery 来管理 DOM;使用 Mustache 来作为模板。它可以和当时流行的框架,很好地结合到一起。在今天看来,能结合其他前端框架,是一件非常难得的事。</p>
<p>遗憾的是,Backbone.js 有一些的缺陷,使它无法满足复杂的前端应用,如 Model 模型比较简单,要处理好 View 比较复杂。除此,还有更新 DOM 带来的性能问题。</p>
<h3 id="angular一站式提高生产力">Angular,一站式提高生产力</h3>
<p>与 Backbone 同一时代诞生的 Angular 便是一个大而全的 MVC 框架。在这个框架里,它提供了我们所需要的各种功能,如模块管理、双向绑定等等。它涵盖了开发中的各个层面,并且层与层之间都经过了精心调适。</p>
<p>我们所需要做的便是遵循其设计思想,来一步步完善我们的应用。Angular.js 的创建理念是:即声明式编程应该用于构建用户界面以及编写软件构建,而命令式编程非常适合来表示业务逻辑。</p>
<p>我开始使用 Angular.js 的原因是,我使用 Ionic 来创建混合应用。出于对制作移动应用的好奇,我创建了一个又一个的移动应用,也在这时学会了 Angular.js。对于我而言,选择合适的技术栈,远远比选择流行的技术栈要重要得多,这也是我喜欢使用 Ionic 的原因。当我们在制作一个应用,它对性能要求不是很高的时候,那么我们应该选择开发速度更快的技术栈。</p>
<p>对于复杂的前端应用来说,基于 Angular.js 应用的运行效率,仍然有大量地改进空间。在应用运行的过程中,需要不断地操作 DOM,会造成明显的卡顿。对于 WebView 性能较差或早期的移动设备来说,这就是一个致命伤。</p>
<p>幸运的是在 2016 年底,Angular 团队推出了 Angular 2,它使用 Zone.js 实现变化的自动检测、</p>
<p>而迟来的 Angular 2 则受<strong>奥斯本效应</strong><a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a>的影响,逼得相当多的开发者们开始转向其它的框架。</p>
<h3 id="react组件化提高复用">React,组件化提高复用</h3>
<p>从 Backbone 和 Angular.js 的性能问题上来看,我们会发现 DOM 是单页面应用急需改善的问题——主要是DOM 的操作非常慢。而在单页面应用中,我们又需要处理大量的 DOM,性能就更是问题了。于是,采用 Virtual DOM 的 React 的诞生,让那些饱受性能苦恼的开发者欢迎。</p>
<p>传统的 DOM 操作是直接在 DOM 上操作的,当需要修改一系列元素中的值时,就会直接对 DOM 进行操作。而采用 Virtual DOM 则会对需要修改的 DOM 进行比较(DIFF),从而只选择需要修改的部分。也因此对于不需要大量修改 DOM 的应用来说,采用 Virtual DOM 并不会有优势。开发者就可以创建出可交互的 UI。</p>
<p>除了编写应用时,不需要对 DOM 进行直接操作,提高了应用的性能。React 还有一个重要思想是组件化,即 UI 中的每个组件都是独立封装的。与此同时,由于这些组件独立于 HTML,使它们不仅仅可以运行在浏览器里,还能作为原生应用的组件来运行。</p>
<p>同时,在 React 中还引入了 JSX 模板,即在 JS 中编写模板,还需要使用 ES 6。令人遗憾的是 React 只是一个 View 层,它是为了优。为了完成一个完整的应用,我们还需要路由库、执行单向流库、web API 调用库、测试库、依赖管理库等等,这简直是一场噩梦。因此为了完整搭建出一个完整的 React 项目,我们还需要做大量的额外工作。</p>
<p>大量的人选择 React 还有一个原因是:React Native、React VR 等等,可以让 React 运行在不同的平台之上。我们还能通过 React 轻松编写出原生应用,还有 VR 应用。</p>
<p>在看到 Angular 2 升级以及 React 复杂性的时候,我相信有相当多的开发者转而选择 Vue.js。</p>
<h3 id="vue.js简单也是提高效率">Vue.js,简单也是提高效率</h3>
<p>引自官网的介绍,Vue.js 是一套构建用户界面的渐进式框架,专注于MVVM 模型的 ViewModel 层。Vue.js 不仅简单、容易上手、配置设施齐全,同时拥有中文文档。</p>
<p>对于使用 Vue.js 的开发者来说,我们仍然可以使用 熟悉的 HTML 和 CSS 来编写代码。并且,Vue.js 也使用了 Virtual DOM、Reactive 及组件化的思想,可以让我们集中精力于编写应用,而不是应用的性能。</p>
<p>对于没有 Angular 和 React 经验的团队,并且规模不大的前端项目来说,Vue.js 是一个非常好的选择。</p>
<p>虽然 Vue.js 的生态与 React 相比虽然差上一截,但是配套设施还是相当齐全的,如 Vuex 、 VueRouter。只是,这些组件配套都由官方来提供、维护,甚至连 awesome-vue 也都是官方项目,总觉得有些奇怪。</p>
<p>除此,Vue.js 中定义了相当多的规矩,这种风格似乎由 jQuery 时代遗留下来的。照着这些规矩来写代码,让人觉得有些不自在。</p>
<p>和 React 相似的是,Vue.js 也有相应的 Native 方案 Weex,仍然值得我们期待。</p>
<h3 id="小结-1">小结</h3>
<p>除了上面提到的这些前端框架,我还用过 Reactive、Ember.js、Mithril.js,遗憾的是同 Vue.js 一样,我没有在大一点的、正式项目上用过。也因此,我没有能力、经验、精力去做更详细的介绍。有兴趣的读者,可以做更详细的了解,也可以在 GitHub (<a href="https://github.com/phodal/fe" class="uri">https://github.com/phodal/fe</a>) 上给我们提交一个 Pull Request。</p>
<h2 id="总结">总结</h2>
<p>今天,大部分的框架并不只是那么简单。为了使用这个框架你,可能需要学习更多的框架、知识、理论。一个很好的例子就是 React,这个框架的开发人员,引入了相当多的概念,JSX、VIrtual Dom。而为了更好地使用 React 来开发,我们还需要引入其他框架,如 Redux、ES6 等等的内容。</p>
<p>这些框架从思想上存在一些差异,但是它们都有相似之处,如组件化、MV**、All in JS、模板引擎等等。欲知后事如何,请期待下一章“前端=模板 + 数据,这就是模板引擎”。</p>
<h1 id="前端基础知识">前端基础知识</h1>
<h2 id="准备工作">准备工作</h2>
<p>为了编写代码,我们需要一些额外的工作。</p>
<p><strong>一个可以帮助你调试的 Chrome 浏览器</strong>。这个浏览器我从他的版本号,还是个位数时就开始用了。这个浏览器在不断地添加新的功能,但是它还没改掉消耗大量内存的毛病。</p>
<p><strong>一个可以让你编写代码的工具</strong>。使用 WebStorm 作为 IDE 也相当的不错。又或者是强大的两个编程器 Vim、Emacs,只是它们的学习曲线有些长,建议初学者:先以学习前端知识为主,工具可在熟悉后再练习。Atom 和 Visual Studio Code 也很不错,。Sublime 是一个轻量级的选择,速度相对于 IDE 快,并且有大量的插件可以使用,还能让你一直免费试用。</p>
<p>还需<strong>一些 Node.js 的知识</strong>。可以将Node.js作为构建语言使用,对于一个成熟的语言来说,构建工具和构建语言是必须的。又或者你想用 JavaScript 作为后台语言,应该学好 Node.js。</p>
<p>初学的时候,准备这些东西,已经让我有了放弃的想法。浏览器是一个很简单的选择,而从琳琅满目的开发工具中选择一个,就不是那么轻松了。</p>
<p>我花了几天的时间,去了解开发者需要怎样的工具,同样的也花了几天去了解这些工具。在我还没写代码的时候,就已经浪费了很多天的时间,这真是罪过啊。俗话说得好:万事开头难,过了这个坑接下来的日子就“轻松”了。</p>
<p>最后,<strong>你肯定要有一台计算机</strong>,最好可以是 GNU/Linux 操作系统,诸如 Mint、Ubuntu、OpenSuSE,你可以对操作系统有更多的控制权。Mac OS X 也是一个非常好的选择,它有一个漂亮的界面,并且大部分的 GNU/Linux 操作系统上的软件,都可以在上面运行。它就是贵,并且不那么“自由”。不过,我相信大部分的读者使用的是 Windows。</p>
<p>开始学习前端的时候,我使用的是一台安装有 Windows 7 家庭版操作系统的 ThinkPad 笔记本。影响我切换到 OpenSuSE 的一个主要原因是,运行不起整套的 Web 环境。一个完整的 Web 系统,不仅仅只有 Web 应用本身,还需要有 HTTP 服务器,应用容器等等的软件。</p>
<p>并且,如果你在使用 Node.js 来开发应用的话,你会发现有相当多的 Node.js 库没有办法成功编译。</p>
<p>好了,这下花了几天的时间,我们终于可以继续三个月之旅了。</p>
<h2 id="编写一个简单的-html">编写一个简单的 HTML</h2>
<p>HTML 让我联想到了 XML,它们的结尾都是 ML。ML<sup>Markup Language</sup> 的意思是『标记语言』,HTML<sup>HyperText Markup Language</sup> 的意思是『超文本』。直到今天我才想明白,为什么那对情侣在学习的时候很害羞。</p>
<p>HTML 是一个特别简单的语言,我再也找不到更简单的语言了。但是为了运行起 HTML,我们仍然也花费了不少的功夫。</p>
<pre><code><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html></code></pre>
<p>如果你需要更多的工具,可以看看我的百宝箱:<a href="https://github.com/phodal/toolbox" class="uri">https://github.com/phodal/toolbox</a>,里面可是收藏了不少的好东西。</p>
<p>后来,BE 学了 PHP 语言,FE 学的是 JavaScript,他们喜欢天天一起撕逼:哪个语言才是最 x 的语言。好在他们又有了一个共同的特点,天天制造 $,才没有分手。</p>
<h2 id="漂亮的-css">漂亮的 CSS</h2>
<h2 id="javascript-居然是小三">JavaScript 居然是小三</h2>
<p>最多的比喻是雷锋与雷锋塔的故事,但是这个比喻是反着过来的,这样一来是先有 JavaScript,才有 Java 的。实际上,是先有阿里巴巴与四十个大盗的故事,才有借着他们名气的阿里巴巴。</p>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p>TC39 是负责 JavaScript 进化的委员会。TC39 定期举行会议,其会议是由成员公司(主要的浏览器厂商)派代表和特邀专家出席了会议。<a href="#fnref1">↩</a></p></li>
<li id="fn2"><p>颇受欢迎的个人电脑厂商奥斯本,其公司的创新式便携电脑还没有上市,就宣布他们要推出的更高档的机器,而又迟迟无法交货,消费者闻风纷纷停止下单订购现有机种,最后导致奥斯本因收入枯竭而宣布破产。<a href="#fnref2">↩</a></p></li>
</ol>
</section>
</body>
</html>