JavaScript编程精解(原书第3版)
上QQ阅读APP看书,第一时间看更新

为什么语言很重要

在计算机诞生之初,没有编程语言。程序看起来像是这样的:

这是一个将数字从1到10加在一起并打印出结果的程序:1 + 2 + … + 10 = 55。它可以运行在一台简单的虚拟机器上。要对早期的计算机进行编程,必须在正确的位置设置大型开关阵列,或者在纸带上打孔并将它们送入计算机。你可以想象编写这种程序是多么乏味和容易出错。即使编写简单的程序也需要很多聪明才智和规则。编写复杂的程序几乎是不可思议的。

当然,手动输入这些神秘的二进制位(1和0)模式确实给程序员一种强烈的成就感,仿佛自己成了魔法师。在工作满意度方面,这一定非常令人满足。

先前程序的每一行都包含一条指令。它可以用如下中文表达:

(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的值。

虽然这已经比一堆二进制位的可读性更好,但它仍然相当难懂。用名称代替数字来指代指令和内存位置会有所改善。

你能看出这个程序是如何运作的吗?前两行为两个内存位置提供了它们的起始值:total将用于构建计算结果,count将跟踪我们当前正在查看的数字。使用compare的行可能是最奇怪的。此程序想要查看count是否等于11来决定它是否可以停止运行。因为我们的虚拟机器相当原始,它只能测试一个数字是否为零并据此做出决定。因此,它使用标记为compare的内存位置来计算count -11的值,并根据此值来做决策。接下来的两行将count的值添加到结果中,并且每当程序确定count不是11时,把count增加1。

下面是JavaScript中的相同程序:

这个版本为我们提供了一些改进。最重要的是,没有必要再次指定程序来回跳转的方式。while结构负责这一点。只要它给出的条件成立,它将继续执行它下面的代码块(用括号括起来的部分)。条件是count <= 10,这意味着“count小于或等于10”。我们不再需要创建临时值并将其与零进行比较,这只是一个无趣的细节。编程语言的部分功能就在于可以为我们处理无趣的细节。

在程序结束处,在while结构完成之后,console.log操作用于写出结果。

最后,如果我们正好有方便的range和sum操作可用,可以分别创建一个范围内的数字集合并计算数字集合的总和,例如下面的这个程序:

这个故事的寓意是,同一个程序的表达方式可长可短,可读性有好有坏。程序的第一个版本非常晦涩难懂,而最后一个版本几乎是一句直白的话:记录(log)从1到10的数字范围(range)内的总和(sum)。(我们将在后面的章节中看到如何定义像sum和range这样的操作。)

一种好的编程语言可以帮助程序员讨论计算机必须在更高级别执行的操作。它有助于省略细节,提供方便的构件(例如while和console.log),允许你定义自己的构件(例如sum和range),并使这些构件易于组合。