当个人电脑刚刚面市的时候,大部分机器都会带有一个简单的编程语言,通常是Basic语言的变体。通过编程语言人们与电脑的交互更紧密起来了,因此每一个电脑用户,无论是否对编程感兴趣,他们都可以尝试一下。现在计算机变得数量众多而且价格便宜,一般的用户除了用鼠标指指点点外不会再更近一步的使用它了。对于大多数人来说,这并没有什么不好。但是对于技术有一种天然的不满倾向的人们,程序设计语言的缺少使电脑的日常使用显得乏味不堪。

庆幸的是,受万维网发展的影响,现在的每台电脑上都配有一个拥有程序设计语言JavaScript环境的现代浏览器。在现如今不要用技术细节打扰用户的原则指导下,这个环境很好的被隐藏起来,但是一个网页可以让我们来领略它,把它作为一个学习程序设计的平台。

本书试图做的就是这个。

                                         。。。。。。。。。。。。。。。

不愤不启,不悱不发,举一隅不以三隅反,则不复也。 ——孔子

除了解释JavaScript,这本书还试图介绍编程的基本原则。编程,其实很难。最基本的原则往往都是简单且清晰。但是,程序,建立它们的基本原则之上,往往复杂的难以言说。正因为此,编程是很不简单,很难描述的事情。正如高纳德,这个领域的奠基人所说,编程是一门艺术。

从此书获益,而不是漫不经心的阅读。保持警觉,努力解决练习,只有在确信弄懂了先前的所有问题之后再继续阅读。

 负责任的计算机程序员是宇宙的创造者。现实中的无限复杂可以用计算机程序的形式被制造出来。 ——约瑟夫·魏泽鲍姆 (《Computer Power and Human Reason》)

一个程序可以意味着很多事情。它是程序员敲打出的一段文本,它是让计算机运作的一套指令,它是内存中的数据,它还是同样内存中动作的控制者。把程序与我们熟悉的事物进行对比进而找到它们的相似性很难,但是我们可以粗略地来跟机器来类比一下。一块机械表的众多齿轮巧妙地互相配合,如果表的制作者很优秀的话,它可以在好几年内准确地显示时间。一个程序的的各个元素也是以这种方式配合在一起工作,如果程序员明确知道他在做什么,那这个程序就会运行无误。

计算机就是作为那些无形的机器的载体的机器。计算机本身只会做直来直去的事情。让计算机有用的原因是它们以难以置信的速度做这些事情。程序可以巧妙把这些简单动作结合起来,做非常复杂的事情。 对我们中的有些人来说,写计算机程序是一个引人入胜的游戏。程序是思想的凝聚。在我们的双手之下,它无需花钱构建,没有重量,而且易于成长。如果我们投入其中,它的大小和复杂会无法控制,困扰它的编写者。这就是编程的主要问题。这就是为什么现如今这么多的软件容易崩溃,失败,把事情弄得一团糟。

当一个程序正常工作时,是很美妙的。编程的艺术就是对复杂性的控制。好程序是顺从的,它化繁为简。

现在,众多的程序员相信复杂性已经被他们撰写的程序很好的控制起来,这些程序用一些少量的易于理解的技术实现。他们已经建立了严格的规则来约束程序应该具有的形式,他们中那些更有热忱的人会指出那些违禁者为不合格的程序员。

丰富多彩的编程里面有多少矛盾啊!努力去减少它们让事情变得直白和可以掌控,视古怪且漂亮的程序为禁忌。编程技术具有非常广阔的内容,具有迷人的多样性,仍然有大量的领域未被探索。编程充斥着陷阱和圈套,引诱没有经验的程序员去犯各种可怕的错误,这意味着你应当要多加小心,保持警惕。在你学习的过程中,总会有许多新的挑战和需要探索的新领域。拒绝保持探索精神的程序员会丧失活力,忘记乐趣,失去编程的意志(会堕落成管理者)。

就我个人来讲,我最关心的是程序的正确性。效率,简洁,大小也很重要,但是如何平衡这些在彼此之间需要抉择,是每一位程序员都必须做出的抉择。经验是有用的,但是不要惧怕打破既有的经验。

在计算机诞生的初期,没有程序设计语言,程序就像这样:

00110001 00000000 00000000
00110001 00000001 00000001
00110011 00000001 00000010
01010001 00001011 00000010
00100010 00000010 00001000
01000011 00000001 00000000
01000001 00000001 00000001
00010000 00000010 00000000
01100010 00000000 00000000

 这是一个把从1到10的数字相加的程序,并输出结果(1 + 2 + ……+ 10 = 55)。它可以在一个很简单的计算机上执行。给早期的计算机编程,需要设置大量的排列和选择在正确的位置上或者在长长的厚纸板上打孔然后把它放入计算机中。你可以想象这是多么乏味的事情,而且还是一个容易出错的过程。即使是简单的程序也需要聪明才智和大量的训练,复杂的就简直就难以想象了。

当然,手工的输入这些神秘的比特 (那些‘0’和‘1’的一般叫法) 确实让程序员觉得自己拥有巫师一样强大的魔力。而且能够获得相当大的成就感,在这方面倒是很值得的。

程序的每一行都是一条单独的指令。用日常的语言可以这样描述:

  1.  将数字0放入位置0
  2.  将数字1放入位置1
  3.  将位置1中的数字放入位置2
  4.  从位置2中的数字中减去11
  5.  如果位置2中的数字为0,就继续执行第9步
  6.  将位置1中的数字加上位置0中的数字
  7.  将位置1中的数字加上1
  8.  继续步骤3
  9.  输出位置0中的值

 这样一来比那一堆二进制好读多了,可是依然让人不爽。用名字来代替步骤和内存位置会更有帮助:

 

  1. Set 'total' to 0
  2. Set 'count' to 1
  3. [loop]
  4. Set 'compare' to 'count'
  5. Subtract 11 from 'compare'
  6. If 'compare' is zero, continue at [end]
  7. Add 'count' to 'total'
  8. Add 1 to 'count'
  9. Continue at [loop]
  10. [end]
  11. Output 'total'

 

 到现在为止,要看出程序是如何工作的就不太困难了。是不是?头两行给出初始值的内存位置: total将被用于放置程序的最终值,而count 则跟踪当前要加入计算的值。用于比较(compare)的那一行恐怕是最让人费解的了。此时程序要做的是看看计数器(counter)是否等于11,来判断是否应该停止运行。因为机器是如此的笨拙,它只能判断一个数字是否为0,然后据此来做出抉择。所以它就用内存位置标为compare的来计算count - 11, 然后根据结果作出判断。接下来两步将count的值加入total,然后程序决定在count还不够11的时候给count加上1。

下面是用JavaScript写的具有同样功能的程序:

 

  1. var total = 0, count = 1;
  2. while (count <= 10) {
  3. total += count;
  4. count += 1;
  5. }
  6. print(total);

 

 这段程序给出了一些新的改观。最重要的改变就是不需要指定跳转和返回的方式了。while这个奇妙的单词会起同样的作用。它意味着只要条件满足所给的count <= 10,就会执行它下面的命令,count <=10的意思是count小于或者等于10。很显然, 现在没有必要再创建一个临时的值然后在跟0去比较了。这些都是愚蠢的小细节,而强大的编程语言会为我们打点这些愚蠢的小细节。 

如果我们拥有更方便的操作符range和sum,它们分别用于创建一系列连续的数字和计算一系列数字的和:

 

  1. print(sum(range(1, 10)));

 

从上述例子中可以看出,同样的程序可以被表示成或长或短,易读或难以阅读的不同形式。这个程序的第一种写法极其难读,而最后一个几乎全是人话:“将从一到十的数的和打印出来(print the sum of range of number from 1 to 10)”,(我们将在稍后的章节里讲述如何创建诸如sum和range之类的东西)。

一种好的程序设计语言会提供一种更抽象的方式来帮助程序员来表达他们的意图。它会隐藏没有意义的东西,提供可以方便构建模块的机制 (比如while结构),还有,很多时候也允许程序员添加他们自己的模块(比如sum和range)。

。。。。。。。。。。。。。。

JavaScript正是这种语言,目前,它多被用于处理web页面上面的各种事情。许多人宣称JavaScript的下一个版本将会变成处理其他事物的重要语言。我不知道会不会实现,但是如果你对程序设计感兴趣的话,JavaScript确实是一种值得学习的有用的语言。即使你以后不会从事大量的web页面编程工作,我将要展示展示给你的那些令人费解的程序仍然会伴随着你,困扰着你,然后会影响你用其他语言写的程序。

确实有一些人对JavaScript有不好的评价。而且许多都是中肯的。我头一次需要用JavaScript写东西的时候,立刻就开始轻视这门语言。它接受了我所写的大部分代码,但是却用其他方式来理解我的意图。这与我对我做的事情没有头绪有很大的关系,但是一个事实就是:JavaScript对它所允许的事情有着近乎荒诞的自由。这种设计的背后意义是会让初学者用JavaScript编程更加容易。事实上,这会让从你程序中找到错误更加困难,因为系统不会为你将之指出。

不过,语言的灵活性又是一种优势。会为很多其他语言无法实现的技巧留下空间,这方面的优势克服了JavaScript的缺点。当我正确的学习它之后,我真的越来越喜欢这门语言了。

。。。。。。。。。。。。。。

与这门语言的名字所暗示的截然相反,JavaScript与Java关系不大。相似的名字是出于市场的考虑。在1995年,网景推出JavaScript的时候,Java语言已经炙手可热,得到了很大的发展。很显然,搭乘这股东风是一个很好的主意。顺理成章地,我们看到了这个名字。

和JavaScript密切相关的是ECMAScript。当除了Netscape之外的浏览器开始支持JavaScript之后,一份精确描述这种语言该如何工作的文档撰写了出来。这份文档被称作ECMAScript,是根据制作这份标准的组织而起的名字。

ECMAScript描述了一种通用目的的编程语言,对它跟互联网浏览器的集成只字未提。JavaScript 是ECMAScript 加上额外工具用来处理互联网网页和浏览器窗口的。

其他一些软件也使用ECMAScript文档中所描述的语言。更重要的是,Flash所用的ActionScript语言正是基于ECMAScript,尽管它不是完全遵守标准)。Flash是一种为web页面添加动态元素使得页面更为热闹的系统。懂得JavaScript会对当你发现你想学习构建Flash动画时有帮助。

当我写这部书时,人们正在为ECMAScript 4而努力。这是ECMAScript的一个新的版本,它添加了很多新特性。你不用担心新版本会使你从此书中学习的东西变得毫无用处。首先,ECMAScript 4 将会是当前这门语言的一个扩展,所以这本书里所描述的内容会依然得到保留。更重要的是,当前主流浏览器增添这些新功能会用上相当长的一段时间,直到它们支持的时候,ECMAScript4也不会被大量使用。

。。。。。。。。。。。。。。

这本书的大部分章节都有大量的代码。根据我个人的经验,阅读和写大量的代码是学习编程的重要部分。试着不仅仅是粗略地浏览它们,而是仔细地研读且理解它们。刚开始的时候会十分困惑,进展缓慢,但是很快你就会找到编程的诀窍。练习也请如此进行。直到你确实写出一个可以工作的解决方案之前,请不要以为你理解了它们。

因为网页的特点,使得查看人们在网页里面放置的JavaScript程序变得可能。学习一些功能是如何写成的,这是一种好的方式。因为大部分web程序员的不“专业”,或者他们认为用JavaScript编程是没有意思的事情,甚至都没有正确的学习它,许多你可以找到的代码质量非常的差。你从丑陋或者不正确的代码中学习,只能使你的代码也变得丑陋,所以学的时候一定要小心。

。。。。。。。。。。。。。。

为了能够使你运行例子和你自己写的代码,此书提供了一个控制台。如果你使用现如今流行的图形界面浏览器(Internet Explorer  6 或更高版本, Firefox 1.5 或更高版本, Opera 9 或更高版本,Safari 3 或更高版本), 这本书的页面会在屏幕底部显示一个横条。你可以单击横条最右边的小箭头来打开控制台。

控制台有三个重要的东西。输出窗口用来显示错误信息和程序输出的东西。输出窗口底部有一个输入框,用来输入一句javaScript代码。试着输入一个数字,然后按回车键,来运行你输入的代码。如果你输入了一些有意义的文本,将会在输出窗口展现出来。现在试着输入一些错误代码,然后再次回车。输出窗口会展示一个错误信息。你可以用向上键和向下键来找回原来输入的命令。

对于大量的代码,你希望保存的多行程序,你可以放在右边的区域中。“Run”按钮被用来执行这个区域中的程序。还有可能会有多个程序同时执行。用“New”和“Load”按钮来添加一段程序(空的或者来自web的文件。)当不止一个程序被打开时,“Run”按钮旁边的菜单用来选择哪个将被执行。“Close”按钮,正如你所想象的,被用来关闭一个程序。

这本书中的例程的左上角一般会有一个小红箭头的按钮,是用来运行它们的。我们先前看到的例子是这样的:

 

  1. var total = 0, count = 1;
  2. while (count <= 10) {
  3. total += count;
  4. count += 1;
  5. }
  6. print(total);

 

如果要运行它就单击箭头。还有另外一个按钮,是用来将程序载入控制台的。当想要修改程序后观察结果的时候,不要犹豫。最坏发生的情况也不过是制造一个死循环。一个死循环就是while之后的条件永远也不会为假,比如如果count变量每次加的数字变为0。现在程序将会永远运行。

幸运的是,浏览器会观察在其内部运行的程序。当一个程序非常可疑地长久运行而未停止,浏览器会询问你是否要停止它的运行。

。。。。。。。。。。。。。。

在稍后的章节里,我们会构建还有多块代码的例程。一般地,你可以单独地运行它们中的其中一个来运行。你可能已经注意到了,代码块运行之后箭头变成了紫色。当你读每一章节的时候,试着运行你所遇见的每一个代码块,特别是有那些你所不熟悉的新东西的时候。(在下一章你将看到它们到底是什么意思)。

当然了,有时候你不可能一口气读完一个章节。这意味着你开始阅读的时候会从中间开始,但是你没有从章节开始就运行所有代码,有些代码可能不工作。在点击run按钮的同时按住shift键,之前所有的代码块都会正常运行,所以当你从章节中间开始阅读时,按住shift键就会使所有代码运行正常。

。。。。。。。。。。。。。。

 

最后,那个屏幕左上角的小脸图标可以用来给我发送信息。如果您有什么看法,或者你发现了一个可笑的错误,又或者你看到了一个拼写错误,请告诉我。发送信息可以不用离开页面就可完成,所以不会打扰你阅读。