第一章 出世
我出生在上古时代的浏览器中,那个时候的网页真的是乏善可陈,你可能都想象不到,主要是那些丑陋的静态文本和简单的图片,和现在美轮美奂的页面相比,差的实在太远了。
那个时候的人们还在用猫通过电话线拨号上网,这还不算什么,网速只有28Kb/s,下载一个网页都得其耐心地等待半天。
我的主人Brendan Eich又一次用公司的网络上网购物时,需要注册用户,添了一个表单,点击了提交按钮,等待了28秒钟,然后服务器告诉他:“对不起,您忘记选择性别了。”
他几乎要崩溃了:“怎么能够这样?这么简单的问题浏览器怎么不告诉我,还得让我把数据提交到几千公里外的服务器网站,然后在那里检查才能发现问题吗?”
对浏览器的改革势在必行!
他于是去找老板:“我实在是忍受不了了,我需要一种脚本运行在浏览器中,帮助我完成这些本来就应该在浏览器中完成的任务。”
老板说:“我正有此意,要不你来设计一个吧”
“好啊,你听说过LISP吗?我们为啥不把LISP运行在浏览器中呢?”
“谁会用啊。。。我们正在和Sun公司合作,你听过他们刚刚发明的Java吗?那个运行在浏览器中的Applet简直酷毙了,Java一定是未来的网络语言。所以你要搞一个新语言出来,要和Java足够想死,但是要比Java简单的多得多,这样那些网页开发人员就可以用了。”
主人很郁闷,但是也没有办法,他对Java毫无兴趣,为了应对公司的任务,他十天就将我设计出来了!我原本叫做LiveScript,为了向Java示好,我改名叫做JavaScript!
由于设计时间太短,我的一些细节考虑的不够严谨,导致后来很长一段时间,JavaScript写出来的程序混乱不堪。如果主人预见到,未来这种语言会成为互联网第一大语言,全世界有成千上万的学习者,他会不会多花一点时间呢?
第二章 成长
Java是当时的明星语言,年轻,活力四射,他经常嘲笑我:你小子是个计算机语言吗?
我说:“是啊,我跟你的语法差不多呢。”
Java:“那为什么你只能在浏览器中运行啊?你能写个程序单独运行吗?哎对了你能读取一个文件吗?”
我当然读取不了文件,我生活在浏览器里,用我写的程序只能嵌入在HTML网页中,由浏览器来执行。他们给这个执行模块起了个很动感的名字:JavaScript引擎。
于是我反击道:“我有个引擎你知道吗?”
“我还有个虚拟机呢。。。”
年长的C也问我,你怎么不编译运行啊?你看我编译之后,运行的多快。
不仅仅是Java和C,当时流行的语言都瞧不起我,背地里叫我屌丝。也是,我没法独立运行,也不能像他们一样画出漂亮的界面,我能做的就是操作HTML的DOM和浏览器。
你可能不知道DOM是什么东西,这么说吧,浏览器从服务器渠道HTML网页之后,会展示成页面让你看,但是内部其实会把HTML组织成一个树让我看,这个数可以称为DOM。例如这个页面:
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<p>hello world!</p>
</body>
</html>
DOM树长这样:
![](https://i-blog.csdnimg.cn/blog_migrate/6192c62e0d5bab595ceeeca64ee3db30.jpeg)
有了这棵树,我就能定位到DOM树中的任何一个节点,然后对这个节点进行操作,例如隐藏节点,显示节点,改变颜色,获得文本的值,改变文本的值,添加一个响应点击事件的函数等等,几乎可以为所欲为了。
更重要的是,这些操作可以立刻显示出来,你完全不用刷新页面。
注意这些操作完全是在内部进行的,HTML源码并不会改变,所以有时候你打开HTML源码,会发现这些源码和你在浏览器中看的效果并不一致,那就是我在背后改变了这个DOM树。
我的主人最初遇到的问题简直就是小菜一碟,做个简单的表单验证,太简单了。
不只是操作DOM,我还能控制浏览器,比如打开窗口,在一个窗口内前进,后退,获得浏览器的名称,版本等。
你可能要问了,为啥还要获得浏览器的名称和版本呢?
说来惭愧,在浏览器进行战争这期间,他们都争相在自己的浏览器中支持JavaScript,为了锁定程序员,还开发了许多自己浏览器的独特功能们有些功能只能IE用,有些只能别的用,所以判断什么浏览器才能进行特殊处理。
不管怎么说,我的这些本市让浏览器中的王也变得更加动态了,更加有趣好玩了。但是也仅限于此,我背困在浏览器和网页上,别的什么也干不了
用Java的话来说,这些都是雕虫小技,奇技淫巧,只是一个打着我的羊头卖狗肉的屌丝而已。
第三章 第一桶金
互联网的发展超出了所有人的预料,我背应用在几乎每一个网站上,但是我一直很苦闷:作为一门语言,我只能在浏览器中运行,没法像Java那样访问网络,也就没有办法调用服务器端的接口来获取数据。
用户只能通过GET或者POST向服务器发送请求(
http://chuansong.me/n/335121851044),这时候服务器返回的数据时整个页面,而不是一个片段,也就是说整个页面都得刷新一遍,哪怕是页面中只有一个文字的改变。
1988年的时候,我和积极进取的IE5做了一次会谈,双方就共同关心的话题深入地交换了意见,最后一致同意,在IE5中引入新功能:XMLHTTPRequest,这个新功能将允许我直接向服务器发出接口调用!
每当发起调用时,IE5通常会这么说:“小JS啊,来,你拿这个用户名和密码去放访问以下服务器端处理登录的接口,这个过程很费时间我就不等你了,先干别的事儿去了,你得到服务器端的返回数据以后,一定要记着调用下我给你的这个函数啊。”
我知道这其实叫做异步调用,于是就乖乖地通过XMLHTTPRequest访问那个登陆的url,耐心的等待服务器干完活,把数据传输回来,然后我就去调用那个函数,基本就是把DOM树的某个节点更新一下,例如让那个包含用户名和密码登录框消失,再加一个提示消息:登陆成功,这事儿我很擅长。
如果服务器处理和网络速度都足够快的话,用户就会发现:咦,我没有刷新整个页面,竟然登录了啊。
我和IE都没有料到,这个功能带来了一场革命:这种方式可以使得网页局部刷新,让用户的体验极佳,尤其是Google地图,Gmail等应用让互联网应用火了起来。其他浏览器迅速跟进,也实现了类似功能,各种各样交互性极佳的网站如雨后春笋般出现,慢慢地没人嘲笑我了,因为他们绝望地发现,他们擅长的桌面应用慢慢地都被搬到了互联网上,没人喜欢他们了。
我,JavaScript,掘到了第一桶金,开始走向人生巅峰。
第四章 发明JSON
后来有个好事之徒把哪种处理方式称为AJAX,即
Asynchronous Javascript And XML”(异步JavaScript和XML),其实异步挺好,但是XML就很不爽了。
比如说服务器返回了下面这段xml:
<book>
<isbn>978-7-229-03093-3</isbn>
<name>三体</name>
<author>刘慈欣</author>
<introduction>
中国最牛的科幻书
</introduction>
<price>38.00</price>
</book>
真正的数据很少,标签反而占了大头,把数据都给淹没了。我对XML说:“你是不是太臃肿了,传输起来多费劲啊。”
XML说:“切,这你就不动了,这样很优雅啊,格式良好,人可以读,程序也可以读啊”
“优雅个啥啊,无用数据这么多,我还得找个解析器解析你,费劲死了”
“你真是屌丝,连个解析也搞不定,你看看人家Java,用
我用的多Happy , Spring, Struts, Hibernate, 几乎所有配置文件都是我。”
Java也在一旁帮抢,是啊,我解析的时候还用DTD校验呢,看看数据合不合法。
阿甘曾经说过,改变不了别人,那就改变一下自己吧。
我看了一下我的语法,里面有个叫对象的东西,它有一个花括号,在括号内部,对象的属性以名称和值对的形式来定义,属性由逗号分隔,像这样:
var book = {
"isbn": "978-7-229-03093-3”,
"name": "三体”,
"author": "刘慈欣”,
"introduction": "中国最牛的科幻书”,
"price": "38.00”
}
这种结构完全可以表达上面的XML内容啊。而且我的语法还支持数组,这样表达多个对象也不在话下啊:
var books = [
{
"isbn": "978-7-229-03093-3”,
"name": "三体”,
"author": "刘慈欣”,
"introduction": "中国最牛的科幻书”,
"price": "38.00”
},
{
"isbn": "978-7-229-03094-1”,
"name": "我是一个线程”,
"author": "刘欣”,
"introduction": "一个线程的自述”,
"price": "0.0”
}
]
数组和对象都支持嵌套,任何复杂的结构都可以保存。更重要的是,如果采用这种结构,我根本不需要什么解析器去解析了,他就是我语言的一部分,直接拿来用即可。
books[0].name -->返回“三体”
books[1].introduction --> 返回“一个线程的自述”
我把这种简洁的格式称为JSON,并约定以后都采用JSON来传输数据。
第五章 人生巅峰
HTML负责结构,CSS负责展示,而我(加上AJAX,JSON)负责逻辑。于是前段三剑客形成了。
ExtJS, prototype, JQuery 这些框架把前端编程推向另外一个高峰。甚至出现了AngularJS 这样的奇葩,实现了SPA(单一页面应用程序), 实在是难于想象。
我对Java说,Java熊,现在我完全可以在浏览器端实现MVC了,你只要在服务器端通过接口给我提供数据就行了。
但是Java还是给我泼冷水:别得意忘形了,服务器端才是核心,要不你到服务器端试试?
我很诧异:“服务器端?我还真没有想过,住在64G内存,32核的CPU上是什么感觉”
“感觉没你想象的好”,Java没好气的说“多线程编程,很多东西都要加锁,一不留神就掉到坑里。我这里基本一个请求就是一线程来处理,遇到数据库操作,虽然慢的要死,线程也得等待。”
“那不能改成异步操作吗?像我的AJAX一样,数据来了再通知我”我问Java。
“不行,一开始就是这样,现在改不了”
把JavaScript放在服务器端执行怎么样?这个想法够疯狂的。
首先得吧浏览器端的运行环境,就是JavaScript引擎移到服务器端,这个引擎执行JavaScript得足够快,要不Java还不得笑死我。原来的引擎一直不合格,直到Chrome V8的出现,才解决问题。
其次得绕开Java副武器的问题:线程遇到I/O/数据库/网络这样的好事操作,不能等待,得搞成异步处理。
但是的确有人这么做了,在我的创始人发明了我十几年后,又有人把我放到了服务器端。这就是node.js
这下Java无话可说了,虽然他还是对我在服务器端执行持怀疑态度,但越来越多使用node.js的网站证明,JavaScript的确可以再服务器端立足,并且有一个巨大的优势:前段和后端可以使用相同的开发语言,那就是JavaScript。
原来的前段现在也可以毫无阻碍地写后盾程序了,是名副其实的“全栈工程师”。
这就是我,一个屌丝的逆袭,我的创始人绝对想不到十几年后我能成为这么一个高富帅,我估计他夜里经常会想:“唉,当年太仓促了,我要是把JavaScript设计的更好一点就好了。”