JavaScript 王者归来

来源:互联网 发布:服务的端口号为 编辑:程序博客网 时间:2024/05/24 15:37

======================================================
注:本文源代码点此下载
======================================================

javascript 王者归来

作者:月影

清华大学出版社

第一部分 概论

第一章 从零开始

程序设计之道无远弗届,御晨风而返

——杰弗瑞.詹姆士

在人类漫漫的历史长河里,很难找到第二个由简单逻辑和抽象符号组合而成的,具有如此宏大信息量

和丰富多彩内涵的领域。从某种意义上说,当你翻开这本书的时候,你已经踏入了一个任由你制定规则的

未知世界。尽管你面对的仅仅是程序设计领域的冰山一角,但你将透过它,去领悟“道”的奥秘。在接下

来的一段时间内,你会同我一起,掌握一种简单而优雅的神秘语言,学会如何将你的意志作用于它。这种

语言中所蕴涵着的亘古之力,将为你开启通往神秘世界的大门……

1.1 为什么选择javascript?

在一些人眼里,程序设计是一件神秘而浪漫的艺术工作,对他们来说,一旦选定某种编程语言,就会

像一个忠贞的信徒一样坚持用它来完成任何事情,然而我不是浪漫的艺匠,大多数人也都不是,很多时候

我们学习一种新技术的唯一目的,只是为了把手中的事情做得更好。所以,当你面对一项陌生的技术时,

需要问的第一个问题往往是,我为什么选择它,它对我来说,真的如我所想的那么重要吗?

好,让我们带着问题开始。

1.1.1 用户的偏好:b/s 模式

如果你坚持站在专业人员的角度,你就很难理解为什么b/s 模式会那么受欢迎。如果你是一个资深的

程序员,有时候你甚至会对那些b/s 模式的东西有一点点反感。因为在你看来,浏览器、表单、dom 和

其他一切与b/s 沾边的东西,大多是行为古怪而难以驾驭的。以你的经验,你会发现实现同样的交互,用

b/s 来做通常会比用任何一种客户端程序来做要困难得多。

如果你尝试站在用户的角度,你会发现为什么大多数最终用户对b/s 模式却是如此的青睐。至少你不

必去下载和安装一个额外的程序到你的电脑上,不必为反复执行安装程序而困扰,不必整天被新的升级补

丁打断工作,不必理会注册表、磁盘空间和一切对普通用户来说有点头疼的概念。如果你的工作地点不是

固定的办公室,你日常工作的pc 也不是固定的一台或者两台,那么,b/s 的意义对你而言或许比想象的

还要大。

大多数情况下,客户更偏好使用浏览器,而不是那些看起来比较专业的软件界面,专业人员则恰恰相

反。

总之,用户的需求让b/s 模式有了存在的理由,而迅速发展的互联网技术则加速了b/s 应用的普及。

随着一些优秀的web 应用产品出现,不但唤起了用户和业内人士对ajax 技术的关注,也令web 领域内的

一个曾经被无数人忽视的脚本语言——javascript 进入了有远见的开发人员和it 经理人的视线。于是在你

的手边,也多了现在这本教程。

编写本书的时候,在tiobe 编程社区最新公布的数据中,javascript 在世界程序开发语言中排名第十,

这意味着javascript 已经正式成为一种被广泛应用的热门语言。

1.1.2 在什么情况下用javascript

一路发展到今天,javascript 的应用范围已经大大超出一般人的想象,但是,最初的javascript 是作为

嵌入浏览器的脚本语言而存在,而它所提供的那些用以表示web 浏览器窗口及其内容的对象简单实用,功

能强大,使得web 应用增色不少,以至于直到今天,在大多数人眼里,javascript 表现最出色的领域依然

是用户的浏览器,即我们所说的web 应用的客户端。客户端浏览器的javascript 应用也正是本书讨论的重

点内容。

作为一名专业程序员,当你在面对客户的时候,经常需要判断哪些交互需求是适合于javascript 来实

现的。而作为一名程序爱好者或者是网页设计师,你也需要了解哪些能够带给人惊喜的特效是能够由

javascript 来实现的。总之一句话,除了掌握javascript 本身,我们需要学会的另一项重要技能是,在正确

的时候、正确的地方使用javascript。对于javascript 初学者来说学会判断正确使用的时机有时候甚至比学

会语言本身更加困难。

作为项目经理,我经常接受来自客户的抱怨。因此我很清楚我们的javascript 在带给客户好处的同时

制造了太多的麻烦,相当多的灾难是由被错误使用的javascript 引起的。一些代码本不应该出现在那个位

置,而另一些代码则根本就不应当出现。我曾经寻访过问题的根源,发现一个主要的原因由于javascript

的过于强大(在后面的小节中我们将会提到,另一个同样重要的原因是“脚本诱惑”),甚至超越了浏览

器的制约范围,于是麻烦就不可避免的产生了,这就像你将一个魔鬼放入一个根本就不可能关住它的盒子

里,那么你也就无法预料魔鬼会做出任何超出预期的举动。

毫无疑问,正确的做法是:不要放出魔鬼。所以,javascript 程序员需要学会的第一个技巧就是掌握

在什么情况下使用javascript 才是安全的。

在什么情况下用javascript?给出一个简单的答案是:在任何不得不用的场合使用,除此以外,不要

在任何场合使用!无懈可击的应用是不用,除非你确实无法找到一个更有效更安全的替代方案。也许这个

答案会让读到这里的读者有些郁闷,但是,我要很严肃地提醒各位,由于javascript 比大多数人想象的要

复杂和强大得多,所以它也比大多数人想象得要危险得多。在我的朋友圈子里,许多资深的javascript 程

序员(包括我在内)偶尔也不得不为自己一时疏忽而做出的错误决定让整个项目团队在“脚本泥潭”中挣

扎好一阵子。所以这个建议从某种意义上说也是专家们的血泪教训。最后向大家陈述一个令人欣慰的事实,

即使是像前面所说的这样,在web 应用领域,javascript 的应用范围也仍然是相当广泛的。

?? 在本节的最后三个小节里,我们将进一步展开讨论关于 javascript 使用的话题。

1.1.3 对javascript 的一些误解

javascript 是一个相当容易误解和混淆的主题,因此在对它进一步研究之前,有必要澄清一些长期存

在的有关该语言的误解。

1.1.3.1 javascript 和java

这是最容易引起误会的一个地方,这个java-前缀似乎暗示了javascript 和java 的关系,也就是

javascript 是java 的一个子集。看上去这个名称就故意制造混乱,然后随之而来的是误解。事实上,这两

种语言是完全不相干的。

javascript 和java 的语法很相似,就像java 和c 的语法相似一样。但它不是java 的子集就像java 也

不是c 的子集一样。在应用上,java 要远比原先设想的好得多(java 原称oak)。

javascript 的创造者是brendan eich,最早的版本在netscape 2 中实现。在编写本书时,brendan eich

在mozilla 公司任职,他本人也是javascript 的主要革新者。而更加有名的java 语言,则是出自sun

microsystems 公司的杰作。

javascript 最初叫做livescript,这个名字本来并不是那样容易混淆,只是到最后才被改名为javascript,

据说起同java 相似的名字纯粹是一种行销策略。

尽管javascript 和java 完全不相干,但是事实上从某种程度上说它们是很好的搭档。javascript 可以控

制浏览器的行为和内容,但是却不能绘图和执行连接(这一点事实上并不是绝对的,通过模拟是可以做到

的)。而java 虽然不能在总体上控制浏览器,但是却可以绘图、执行连接和多线程。客户端的javascript

可以和嵌入网页的java applet 进行交互,并且能够对它执行控制,从这一意义上来说,javascript 真的可

以脚本化java。

1.1.3.2 披着c 外衣的lisp

javascript 的c 风格的语法,包括大括号和复杂的for 语句,让它看起来好像是一个普通的过程式语

言。这是一个误导,因为javascript 和函数式语言如lisp 和scheme 有更多的共同之处。它用数组代替了

列表,用对象代替了属性列表。函数是第一型的。而且有闭包。你不需要平衡那些括号就可以用λ 算子。

?? 关于 javascript 闭包和函数式的内容,在本书的第23 章中会有更详细的介绍。

1.1.3.3 思维定势

javascript 是原被设计在netscape navigator 中运行的。它的成功让它成为几乎所有浏览器的标准配置。

这导致了思维定势。认为javascript 是依赖于浏览器的脚本语言。其实,这也是一个误解。javascript 也适

合很多和web 无关的应用程序。

早些年在学校的时候,我和我的实验室搭档曾经研究过将javascript 作为一种pda 控制芯片的动态脚

本语言的可行性,而在我们查阅资料的过程中发现一些对基于嵌入式环境的动态脚本语言实现的尝试,我

们有理由相信,javascript 在某些特定的嵌入式应用领域中也能够表现得相当出色。

1.1.3.4 业余爱好者

一个很糟糕的认知是:javascript 过于简朴,以至于大部分写javascript 的人都不是专业程序员。他们

缺乏写好程序的修养。javascript 有如此丰富的表达能力,他们可以任意用它来写代码,以任何形式。

事实上,上面这个认知是曾经的现实,不断提升的web 应用要求和ajax 彻底改变了这个现实。通过

学习本书,你也会发现,掌握javascript 依然需要相当高的专业程序员技巧,而不是一件非常简单的事情。

不过这个曾经的现实却给javascript 带来了一个坏名声──它是专门为外行设计的,不适合专业的程序员。

这显然是另一个误解。

推广 javascript 最大的困难就在于消除专业程序员对它的偏见,在我的项目团队中许多有经验的j2ee

程序员却对javascript 停留在一知半解甚至茫然的境地,他/她们不愿意去学习和掌握javascript,认为这门

脚本语言是和浏览器打交道的美工们该干的活儿,不是正经程序员需要掌握的技能。这对于web 应用开发

来说,无疑是一个相当不利的因素。

1.1.3.5 面向对象

javascript 是不是面向对象的?它拥有对象,可以包含数据和处理数据的方法。对象可以包含其它对

象。它没有类(在javascript 2.0 真正实现之前),但它却有构造器可以做类能做的事,包括扮演类变量和

方法的容器的角色。它没有基于类的继承,但它有基于原型的继承。两个建立对象系统的方法是通过继承

和通过聚合。javascript 两个都有,但它的动态性质让它可以在聚合上超越。

一些批评说javascript 不是真正面向对象的因为它不能提供信息的隐藏。也就是,对象不能有私有变

量和私有方法:所有的成员都是公共的。但随后有人证明了javascript 对象可以拥有私有变量和私有方法。

另外还有批评说javascript 不能提供继承,但随后有人证明了javascript 不仅能支持传统的继承还能应用其

它的代码复用模式。

说javascript 是一种基于对象的语言,是一种正确而略显保守的判断,而说javascript 不面向对象,

在我看来则是错误的认知。事实上有充足的理由证明javascript 是一种的面向对象的语言,只是与传统的

class-based oo(基于类的面向对象)相比,javascript 有它与众不同的地方,这种独特性我们称它为

prototype-based oo(基于原型的面向对象)。

?? 关于 javascript 面向对象的内容,在本书的第21 章中会有更详细的介绍。

1.1.3.6 其他误解

除了以上提到的几点之外,javascript 还有许多容易令人迷惑和误解的特性,这些特性使得javascript

成为世界上最被误解的编程语言。

?? 如果读者对这方面有兴趣,可以详细阅读下面这篇文章

http://javascript.crockford.com/javascript.html [douglas crockford]

1.1.4 警惕!脚本诱惑

前面我们提到过,许多专业程序员拒绝去了解如何正确使用javascript,另一些则是缺乏对javascript

足够的认知和应用经验。但是在b/s 应用中,相当多的情况下,要求开发人员不得不采用javascript。于

是,一个问题产生了,大量的javascript 代码拷贝出现在页面的这个或者那个地方,其中的大部分是不必

要的,另一部分可能有缺陷。我们的开人员没有办法(也没有意识到)去判断这些代码是否必要,以及使

用它们会带来哪些问题。

如果你的b/s 应用中的javascript 不是由专业的javascript 程序员来维护的,那么当你对你的开发团队

进行一次小小的代码走查时,你甚至可能会发现90%的javascript 代码被错误地使用,这些错误使用的代

码浪费了用户大量的网络带宽、内存和cpu 资源,提升了对客户端配置的要求,降低了系统的稳定性,

甚至导致许多本来可以避免的安全问题。

由于浏览器的javascript 可以方便地被复制粘贴,因此,一个特效或者交互方式往往在真正评估它的

必要性之前便被采用——客户想要它,有人使用过它,程序员复制它,而它就出现在那儿,表面上看起来

很完美,于是,所谓的脚本诱惑就产生了。

事实上,在我们真正使用javascript 之前,需要反复问自己一个重要问题是,究竟是因为有人想要它,

还是因为真正有人需要它。在你驾驭javascript 马车之前,你必须学会抵制脚本诱惑,把你的脚本用在必

要的地方,永远保持你的web 界面简洁,风格一致。

在用户眼里,简洁一致的风格与提供强大而不常用的功能和看起来很cool 而实际上没有什么功用的

界面特效相比起来,前者更能令他们觉得专业。毕竟,大部分用户和你我一样,掌握一个陌生的环境和新

的技能只是为了能够将事情做得更快更好。除非你要提供的是一个类似于qzone 之类的娱乐程序,你永远

也不要大量地使用不必要的javascript。

1.1.5 隐藏在简单表象下的复杂度

专业人员不重视javascript 的一个重要原因是,他们觉得javascript 是如此的简单,以至于不愿意花精

力去学习(或者认为不用学习就能掌握)。前面提到过的,这实际上是一种误解。事实上,在脚本语言中,

javascript 属于相当复杂的一门语言,它的复杂程度未必逊色于perl 和python。

另一个业内的偏见是脚本语言都是比较简单的,实际上,一门语言是否脚本语言往往是它的设计目标

决定的,简单与复杂并不是区分脚本语言和非脚本语言的标准。javascript 即使放到非脚本语言中来衡量,

也是一门相当复杂的语言。

之所以很多人觉得javascript 过于简单,是因为他们大量使用的是一些javascript 中看似简单的文法,

解决的是一些看似简单的问题,真正复杂而又适合javascript 的领域却很少有人选择javascript,真正强大

的用法很少被涉及。javascript 复杂的本质被一个个简单应用的表象所隐藏。

我曾经给一些坚持认为javascript 过于简单的开发人员写过一段小代码,结果令他们中的大部分内行

人大惊失色,那段代码看起来大致像下面这个样子:

var a = [-1,-1,1,-3,-3,-3,2,2,-2,-2,3,-1,-1];

function f(s, e)

{

var ret = [];

for(var i in s){

ret.push(e(s[i]));

}

return ret;

}

var b = f(a, function(n){return n>0?n:0});

alert(b);

这是本书中出现的第一段javascript 代码,也许现在你看来,它有那么一点点令人迷惑,但是不要紧,

在本书后面的章节中,你会慢慢理解这段代码的含义以及它的无穷妙味。而现在你完全可以跳过它的实际

内容,只要需要知道这是一段外表看起来简单的魔法代码就够了。

因为这段代码而尖叫的不仅仅包括我的这些程序员朋友,事实上,更兴奋的是另一些电子领域的朋友,

他们写信给我反馈说,在此之前他们从来没有见到过如此形式简洁而优雅的数字高通滤波器,更令人欣喜

的是,它的阈值甚至是可调节的:

var b = f(a, function(n){return n>=-1?n:0});

如果你想要,它也很容易支持低通滤波:

var b = f(a, function(n){return n

仔细研究它,你会发现,这种函数定义方式,同数学语言的描述方式几乎完全一致!

这种数学形式上的一致性,在传统的过程式语言中,几乎是无法想象的。如果不利用javascript 的函

数式特性,要定义和调用抛物线方程,只能以下面这种丑陋的方式:

function parabola(a, b, c, x)

{

return a * x * x + b * x + c;

}

var y = parabola(2, 3, 4, 15);

如果用面向对象来表示,则问题又有一点点差别:

function parabola(a, b, c)

{

this.evaluate = function(x)

{

return a * x * x + b * x + c;

}

}

var p1 = new parabola(2,3,4); //抛物线y = 2*x^2 + 3*x + 4

alert(p1.evaluate());

面向对象把抛物线当作了“对象”,从自然界的角度来讲,这没有什么问题,然而从数学的角度来讲,

它把问题复杂化了。抛物线本来就是一个方程(函数),不需要再定义成一个对象,然后用蹩脚的evaluate()

来进行求值。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/