JavaScript 编程精解 中文第三版 零、前言

来源: ApacheCN『JavaScript 编程精解 中文第三版』翻译项目

原文:Introductionjavascript

译者:飞龙html

协议:CC BY-NC-SA 4.0java

自豪地采用谷歌翻译git

部分参考了《JavaScript 编程精解(第 2 版)》程序员

We think we are creating the system for our own purposes. We believe we are making it in our own image... But the computer is not really like us. It is a projection of a very slim part of ourselves: that portion devoted to logic, order, rule, and clarity.github

Ellen Ullman,《Close to the Machine: Technophilia and its Discontents》正则表达式

这是一本关于指导电脑的书。时至今日,计算机就像螺丝刀同样随处可见,但相比于螺丝刀而言,计算机更复杂一些,而且,让他们作你想让他们作的事情,并不老是那么容易。数据库

若是你让计算机执行的任务是常见的,易于理解的任务,例如向你显示你的电子邮件,或像计算器同样工做,则能够打开相应的应用并开始工做。 但对于独特的或开放式的任务,应用可能不存在。apache

这就是编程可能出现的地方。编程是构建一个程序的行为 - 它是一组精确的指令,告诉计算机作什么。 因为计算机是愚蠢的,迂腐的野兽,编程从根本上是乏味和使人沮丧的。编程

幸运的是,若是你能够克服这个事实,而且甚至能够享受愚蠢机器能够处理的严谨思惟,那么编程能够是很是有益的。 它可让你在几秒钟内完成手动操做。 这是一种方法,让你的电脑工具去作它之前作不到的事情。 它也提供了抽象思惟的优秀练习。

大多数编程都是用编程语言完成的。 编程语言是一种人工构建的语言,用于指导计算机。 有趣的是,咱们发现与电脑沟通的最有效的方式,与咱们彼此沟通的方式相差太大。 与人类语言同样,计算机语言能够以新的方式组合词语和词组,从而能够表达新的概念。

在某种程度上,基于语言的界面,例如 80 年代和 90 年代的 BASIC 和 DOS 提示符,是与计算机交互的主要方法。 这些已经在很大程度上被视觉界面取代,这些视觉界面更容易学习,但提供更少的自由。 计算机语言仍然存在,若是你知道在哪里看到。 每种现代 Web 浏览器都内置了一种这样的语言,即 JavaScript,所以几乎能够在全部设备上使用。

本书将试图让你足够了解这门语言,从而完成有用和有趣的东西。

关于程序设计

除了讲解 JavaScript 以外,本书也会介绍一些程序设计的基本原则。程序设计仍是比较复杂的。编程的基本规则简单清晰,但在这些基本规则之上构建的程序却容易变得复杂,致使程序产生了本身的规则和复杂性。即使程序是按照你本身的思路去构建的,你也有可能迷失在代码之间。

在阅读本书时,你有可能会以为书中的概念难以理解。若是你刚刚开始学习编程,那么你估计还有很多东西须要掌握呢。若是你想将所学知识融会贯通,那么就须要去多参考和学习一些资料。

是否付出必要的努力彻底取决于你本身。当你阅读本书的时候发现任何难点,千万不要轻易就对本身的能力下结论。只要能坚持下去,你就是好样的。稍作休息,复习一下所学的知识点,始终确保本身阅读并理解了示例程序和相关的练习。学习是一项艰巨的任务,但你掌握的全部知识都属于你本身,并且从此的学习道路会越发轻松。

当行动无利可图时,就收集信息;当信息无利可图时,就休息。

Ursula K. Le Guin,《The Left Hand of Darkness》

一个程序有不少含义:它是开发人员编写的一段文本、计算机执行的一段指令集合、计算机内存当中的数据以及控制内存中数据的操做集合。咱们一般很难将程序与咱们平常生活中熟悉的事物进行对比。有一种表面上比较恰当的比喻,即将程序视做包含许多组件的机器,为了让机器正常工做,这些组件经过内部通讯来实现整个机器的正常运转。

计算机是一台物理机器,充当这些非物质机器的载体。计算机自己并不能实现多么复杂的功能,但计算机之因此有用是由于它们的运算速度很是快。而程序的做用就是将这些看似简单的动做组合起来,而后实现复杂的功能。

程序是思想的结晶。编写程序不须要什么物质投入,它很轻量级,经过咱们的双手创造。

但若是不稍加注意,程序的体积和复杂度就会失去控制,甚至代码的编写者也会感到迷惑。在可控的范围内编写程序是编程过程当中首要解决的问题。当程序运行时,一切都是那么美好。编程的精粹就在于如何更好地控制复杂度。质量高的程序的复杂度都不会过高。

不少开发人员认为,控制程序复杂度的最好方法就是避免使用不熟悉的技术。他们制定了严格的规则(“最佳实践”),并当心翼翼地呆在他们安全区内。

这不只无聊,并且也是无效的。新问题每每须要新的解决方案。编程领域还很年轻,仍然在迅速发展,而且多样到足觉得各类不一样的方法留出空间。在程序设计中有许多可怕的错误,你应该继续犯错,以便你能理解它们。好的程序看起来是什么样的感受,是在实践中发展的,而不是从一系列规则中学到的。

为何编程语言重要

在计算技术发展伊始,并无编程语言这个概念。程序看起来就像这样:

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。该程序能够运行在一个简单的机器上。在早期计算机上编程时,咱们须要在正确的位置设置大量开关阵列,或在纸带上穿孔并将纸带输入计算机中。你能够想象这个过程是多么冗长乏味且易于出错。即使是编写很是简单的程序,也须要有经验的人耗费很大精力才能完成。编写复杂的程序则更是难上加难。

固然了,手动输入这些晦涩难懂的位序列(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 中的值。

虽然说这已经比一大堆位序列要好读了许多,但仍然不清晰。使用名称而不是数字用于指令和存储位置有所帮助:

Set “total” to 0.
 Set “count” to 1.
[loop]
 Set “compare” to “count”.
 Subtract 11 from “compare”.
 If “compare” is zero, continue at [end].
 Add “count” to “total”.
 Add 1 to “count”.
 Continue at [loop].
[end]
 Output “total”.

如今你能看出该程序是如何工做的吗?前两行代码初始化两个内存位置的值:total用于保存累加计算结果,而count则用于记录当前数字。你可能以为compare的那行代码看起来有些奇怪。程序想根据count是否等于 11 来决定是否应该中止运行。由于咱们的机器至关原始,因此只能测试一个数字是否为 0,并根据它作出决策。所以程序用名为compare的内存位置存放count–11的值,并根据该值是否为 0 决定是否跳转。接下来两行将count的值累加到结果上,并将count加 1,直到count等于11为止。

下面使用 JavaScript 从新编写了上面的程序:

let total = 0, count = 1;
while (count <= 10) {
  total += count;
  count += 1;
}
console.log(total);
// → 55

这个版本的程序获得了一些改进。更为重要的是,咱们不再须要指定程序如何来回跳转了,而是由while结构负责完成这个任务。只要咱们给予的条件成立,while语句就会不停地执行其下方的语句块(包裹在大括号中)。而咱们给予的条件是count<=10,意思是“count小于等于 10”。咱们不再须要建立临时的值并将其与 0 比较,那样的代码十分烦琐。编程语言的一项职责就是,可以帮助咱们处理这些烦琐无趣的逻辑。

在程序的结尾,也就是while语句结束后,咱们使用console.log操做来输出结果。

最后,咱们刚好有rangesum这类方便的操做。下面代码中的range函数用于建立数字集合,sum函数用于计算数字集合之和:

console.log(sum(range(1, 10)));
// → 55

咱们能够从这里了解到,同一个程序的长度可长可短,可读性可高可低。第一个版本的程序晦涩难懂,而最后一个版本的程序则接近于人类语言的表达方式:将 1~10 范围内的数字之和记录下来(咱们会在后面的章节中详细介绍如何编写sumrange这样的函数)。

优秀的编程语言能够为开发人员提供更高层次的抽象,使用相似于人类语言的方式来与计算机进行交互。它有助于省略细节,提供便捷的积木(好比whileconsole.log),容许你定义本身的积木(好比sumrange函数),并使这些积木易于编写。。

什么是 JavaScript

JavaScript 诞生于 1995 年。起初,Netscape Navigator 浏览器将其运用在网页上添加程序。自此之后,各种主流图形网页浏览器均采用了 JavaScript。JavaScript 使得现代网页应用程序成为可能 —— 使用 JavaScript 能够直接与用户交互,从而避免每个动做都须要从新载入页面。但有许多传统网站也会使用 JavaScript 来提供实时交互以及更加智能的表单功能。

JavaScript 其实和名为Java的程序设计语言没有任何关系。起了这么一个类似的名字彻底是市场考虑使然,这并不是是一个明智的决定。当 JavaScript 出现时,Java 语言已在市场上获得大力推广且拥有了极高人气,所以某些人以为依附于 Java 的成功是个不错的主意。而咱们如今已经没法摆脱这个名字了。

在 JavaScript 被普遍采用以后,ECMA 国际制订了一份标准文档来描述 JavaScript 的工做行为,以便全部声称支持 JavaScript 的软件都使用同一种语言。标准化完成后,该标准被称为 ECMAScript 标准。实际上,术语 ECMAScript 和 JavaScript 能够交换使用。它们不过是同一种语言的两个名字而已。

许多人会说 JavaScript 语言的坏话。这其中有不少这样的言论都是正确的。当被要求第一次使用 JavaScript 编写代码时,我当时就以为这门语言难以驾驭。JavaScript 接受我输入的任何代码,可是又使用和个人想法彻底不一样的方式来解释代码。因为我没有任何线索知道我以前作了什么,所以我须要作出更多工做,但这也就存在一个实际问题:咱们能够自由使用 JavaScript,而这种自由却几乎没有限度。这种设计实际上是但愿初学者更容易使用 JavaScript 编写程序。但实际上,系统不会指出咱们错在何处,所以从程序中找出问题变得更加棘手。

但这种自由性也有其优点,许多技术在更为严格的语言中不可能实现,而在 JavaScript 中则留下了实现的余地,正如你看到的那样(好比第十章),有些优点能够弥补 JavaScript 的一些缺点。在正确地学习 JavaScript 并使用它工做了一段时间后,我真正喜欢上了 JavaScript。

JavaScript 版本众多。大约在 2000~2010 年间,这正是 JavaScript 飞速发展的时期,浏览器支持最多的是 ECMAScript 3。在此期间,ECMA 着手制定 ECMAScript 4,这是一个雄心勃勃的版本,ECMA 计划在这个版本中加入许多完全的改进与扩展。但因为 ECMAScript 3 被普遍使用,这种过于激进的修改必然会遭遇重重阻碍,最后 ECMA 不得不于 2008 年放弃了版本 4 的制定。这就产生了不那么雄心勃勃的版本 5,这只是一些没有争议的改进,出如今 2009 年。 而后版本 6 在 2015 年诞生,这是一个重大的更新,其中包括计划用于版本 4 的一些想法。从那之后,每一年都会有新的更新。

语言不断发展的事实意味着,浏览器必须不断跟上,若是你使用的是较老的浏览器,它可能不支持每一个特性。 语言设计师会注意,不要作任何可能破坏现有程序的改变,因此新的浏览器仍然能够运行旧的程序。 在本书中,我使用的是 2017 版的 JavaScript。

Web 浏览器并非惟一一个能够运行 JavaScript 的平台。有些数据库,好比 MongoDB 和 CouchDB,也使用 JavaScript 做为脚本语言和查询语言。一些桌面和服务器开发的平台,特别是 Node.js 项目(第二十章介绍),为浏览器之外的 JavaScript 编程提供了一个环境。

代码及相关工做

代码是程序的文本内容。本书多数章节都介绍了大量代码。我相信阅读代码和编写代码是学习编程不可或缺的部分。尝试不要仅仅看一眼示例,而应该认真阅读并理解每一个示例。刚开始使用这种方式可能会速度较慢并为代码所困惑,但我坚信你很快就能够熟能生巧。对待习题的方法也应该同样。除非你确实已经编写代码解决了问题,不然不要假设你已经理解了问题。

建议读者应尝试在实际的 JavaScript 解释器中执行习题代码。这样一来,你就能够立刻获知代码工做状况的反馈,并且我但愿读者去作更多的试验,而不只仅局限于习题的要求。

能够在 http://eloquentjavascript.net...,该网址会提供每一个习题的初始代码,让你专心于解答习题。

若是想要在本书提供的沙箱之外执行本书代码,须要稍加注意。许多的示例是独立的,并且能够在任何 JavaScript 环境下运行。但后续章节的代码大多数都是为特定环境(浏览器或者 Node.js)编写的,并且只能在这些特定环境下执行代码。此外,许多章节定义了更大的程序,这些章节中出现的代码片断会互相依赖或是依赖于一些外部文件。本书网站的沙箱提供了 zip 压缩文件的连接,该文件包含了全部运行特定章节代码所需的脚本和数据文件。

本书概览

本书包括三个部分。前十二章讨论 JavaScript 语言自己的一些特性。接下来的 8 章讨论网页浏览器和 JavaScript 在网页编程中的实践。最后两章专门讲解另外一个使用 JavaScript 编程的环境 —— Node.js。

纵观本书,共有 5 个项目实战章,用于讲解规模较大的示例程序,你能够经过这些章来仔细品味真实的编程过程。根据项目出现次序,咱们会陆续构建递送机器人(7)、程序设计语言(12)、平台游戏(16)、像素绘图程序(19)和一个动态网站(21)。

本书介绍编程语言时,首先使用4章来介绍 JavaScript 语言的基本结构,包括第二章控制结构(好比在本前言中看到的while单词)、第三章函数(编写你本身的积木)和第四章数据结构。此后你就能够编写简单的程序了。接下来,第五章和第六章介绍函数和对象的运用技术,以编写更加抽象的代码并以此来控制复杂度。

介绍完第一个项目实战(7)以后,将会继续讲解语言部分,例如第八章错误处理和 bug 修复、第九章正则表达式(处理文本数据的重要工具)、第十章模块化(解决复杂度的问题)以及第十一章异步编程(处理须要时间的事件)。第二个项目实战章节(12)则是对本书第一部分的总结。

第二部分(第十三章到第十九章),阐述了浏览器 JavaScript 中的一些工具。你将会学到在屏幕上显示某些元素的方法(第十四章与第十七章),响应用户输入的方法(第十五章)和经过网络通讯的方法(第十八章)。这部分又有两个项目实战章节。

此后,第二十章阐述 Node.js,而第二十一章使用该工具构建一个简单的网页系统。

本书版式约定

本书中存在大量代码,程序(包括你迄今为止看到的一些示例)代码的字体以下所示:

function factorial(n) {
  if (n == 0) {
    return 1;
  } else {
    return factorial(n - 1) * n;
  }
}

为了展现程序产生的输出,本书常在代码后编写代码指望输出,输出结果前会加上两个反斜杠和一个箭头。

console.log(factorial(8));
// → 40320

祝好运!

相关文章
相关标签/搜索