js 00

Introduction 引言

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.

我们认为我们是为了自己的目的而创造这个系统。我们相信我们是在按照自己的形象创造它... ... 但是电脑并不真的像我们。它是我们自身非常微小的一部分的投射: 那部分致力于逻辑、秩序、规则和清晰。

Ellen Ullman, Close to the Machine: Technophilia and its Discontents

艾伦 · 乌尔曼,《靠近机器: 技术狂及其不满》

![Picture of a screwdriver and a circuit board](img/chapter_picture_00.jpg)
! [图为螺丝刀和电路板](img/chapter _ Picture _ 00.jpg)

This is a book about instructing computers. Computers are about as common as screwdrivers today, but they are quite a bit more complex, and making them do what you want them to do isn’t always easy.


If the task you have for your computer is a common, well-understood one, such as showing you your email or acting like a calculator, you can open the appropriate application and get to work. But for unique or open-ended tasks, there probably is no application.


That is where programming may come in. Programming is the act of constructing a program—a set of precise instructions telling a computer what to do. Because computers are dumb, pedantic beasts, programming is fundamentally tedious and frustrating.


Fortunately, if you can get over that fact, and maybe even enjoy the rigor of thinking in terms that dumb machines can deal with, programming can be rewarding. It allows you to do things in seconds that would take forever by hand. It is a way to make your computer tool do things that it couldn’t do before. And it provides a wonderful exercise in abstract thinking.


Most programming is done with programming languages. A programming language is an artificially constructed language used to instruct computers. It is interesting that the most effective way we’ve found to communicate with a computer borrows so heavily from the way we communicate with each other. Like human languages, computer languages allow words and phrases to be combined in new ways, making it possible to express ever new concepts.


At one point language-based interfaces, such as the BASIC and DOS prompts of the 1980s and 1990s, were the main method of interacting with computers. They have largely been replaced with visual interfaces, which are easier to learn but offer less freedom. Computer languages are still there, if you know where to look. One such language, JavaScript, is built into every modern web browser and is thus available on almost every device.

在某种程度上,基于语言的接口,如20世纪80年代和90年代的 BASIC 和 DOS 提示,是与计算机交互的主要方法。它们在很大程度上已经被可视化界面所取代,可视化界面更容易学习,但自由度更小。计算机语言仍然存在,如果你知道去哪里找的话。JavaScript 就是这样一种语言,它内置在每一个现代网络浏览器中,因此几乎可以在每一个设备上使用。

This book will try to make you familiar enough with this language to do useful and amusing things with it.


On programming 关于编程

Besides explaining JavaScript, I will introduce the basic principles of programming. Programming, it turns out, is hard. The fundamental rules are simple and clear, but programs built on top of these rules tend to become complex enough to introduce their own rules and complexity. You’re building your own maze, in a way, and you might just get lost in it.

除了讲解 JavaScript,我还会介绍编程的基本原理。事实证明,编程是困难的。基本规则简单明了,但是基于这些规则的程序往往会变得足够复杂,以至于引入了它们自己的规则和复杂性。在某种程度上,你正在建造自己的迷宫,你可能会在其中迷失。

There will be times when reading this book feels terribly frustrating. If you are new to programming, there will be a lot of new material to digest. Much of this material will then be combined in ways that require you to make additional connections.


It is up to you to make the necessary effort. When you are struggling to follow the book, do not jump to any conclusions about your own capabilities. You are fine—you just need to keep at it. Take a break, reread some material, and make sure you read and understand the example programs and exercises. Learning is hard work, but everything you learn is yours and will make subsequent learning easier.


When action grows unprofitable, gather information; when information grows unprofitable, sleep.

当行动变得无利可图时,收集信息; 当信息变得无利可图时,睡眠。

Ursula K. Le Guin, The Left Hand of Darkness


A program is many things. It is a piece of text typed by a programmer, it is the directing force that makes the computer do what it does, it is data in the computer’s memory, yet it controls the actions performed on this same memory. Analogies that try to compare programs to objects we are familiar with tend to fall short. A superficially fitting one is that of a machine—lots of separate parts tend to be involved, and to make the whole thing tick, we have to consider the ways in which these parts interconnect and contribute to the operation of the whole.


A computer is a physical machine that acts as a host for these immaterial machines. Computers themselves can do only stupidly straightforward things. The reason they are so useful is that they do these things at an incredibly high speed. A program can ingeniously combine an enormous number of these simple actions to do very complicated things.


A program is a building of thought. It is costless to build, it is weightless, and it grows easily under our typing hands.


But without care, a program’s size and complexity will grow out of control, confusing even the person who created it. Keeping programs under control is the main problem of programming. When a program works, it is beautiful. The art of programming is the skill of controlling complexity. The great program is subdued—made simple in its complexity.


Some programmers believe that this complexity is best managed by using only a small set of well-understood techniques in their programs. They have composed strict rules (“best practices”) prescribing the form programs should have and carefully stay within their safe little zone.

一些程序员认为,这种复杂性最好通过在他们的程序中使用少量易于理解的技术来管理。他们制定了严格的规则(“最佳实践”) ,规定程序应该有的形式,并小心地留在他们的安全小区内。

This is not only boring, it is ineffective. New problems often require new solutions. The field of programming is young and still developing rapidly, and it is varied enough to have room for wildly different approaches. There are many terrible mistakes to make in program design, and you should go ahead and make them so that you understand them. A sense of what a good program looks like is developed in practice, not learned from a list of rules.


Why language matters 为什么语言很重要

In the beginning, at the birth of computing, there were no programming languages. Programs looked something like this:


[](#c_D6PkB3Wa2f)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

That is a program to add the numbers from 1 to 10 together and print out the result: 1 + 2 + .<wbr>.<wbr>.<wbr> + 10 = 55. It could run on a simple, hypothetical machine. To program early computers, it was necessary to set large arrays of switches in the right position or punch holes in strips of cardboard and feed them to the computer. You can probably imagine how tedious and error-prone this procedure was. Even writing simple programs required much cleverness and discipline. Complex ones were nearly inconceivable.

这是一个把1到10的数字相加并打印出结果: 1 + 2 + 的程序。我不知道你在说什么。我不知道你在说什么。10 = 55.它可以在一个简单的,假设的机器上运行。为了给早期的计算机编程,有必要在合适的位置设置大量的开关阵列,或者在纸板条上打孔,然后将它们输入计算机。您可以想象这个过程是多么的乏味和容易出错。即使编写简单的程序也需要聪明才智和自律。复杂的问题几乎是不可想象的。

Of course, manually entering these arcane patterns of bits (the ones and zeros) did give the programmer a profound sense of being a mighty wizard. And that has to be worth something in terms of job satisfaction.


Each line of the previous program contains a single instruction. It could be written in English like this:


  1. Store the number 0 in memory location 0.


  2. Store the number 1 in memory location 1.


  3. Store the value of memory location 1 in memory location 2.


  4. Subtract the number 11 from the value in memory location 2.


  5. If the value in memory location 2 is the number 0, continue with instruction 9.


  6. Add the value of memory location 1 to memory location 0.


  7. Add the number 1 to the value of memory location 1.


  8. Continue with instruction 3.


  9. Output the value of memory location 0.


Although that is already more readable than the soup of bits, it is still rather obscure. Using names instead of numbers for the instructions and memory locations helps.


[](#c_Z0jlA6dfj3) Set “total” to 0.
 Set “count” to 1.
 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].
 Output “total”.

Can you see how the program works at this point? The first two lines give two memory locations their starting values: total will be used to build up the result of the computation, and count will keep track of the number that we are currently looking at. The lines using compare are probably the weirdest ones. The program wants to see whether count is equal to 11 to decide whether it can stop running. Because our hypothetical machine is rather primitive, it can only test whether a number is zero and make a decision based on that. So it uses the memory location labeled compare to compute the value of count - 11 and makes a decision based on that value. The next two lines add the value of count to the result and increment count by 1 every time the program has decided that count is not 11 yet.

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

Here is the same program in JavaScript:

下面是同一个 JavaScript 程序:

[](#c_KfhVPRGaZ0)let total = 0, count = 1;
while (count <= 10) {
  total += count;
  count += 1;
// → 55

This version gives us a few more improvements. Most important, there is no need to specify the way we want the program to jump back and forth anymore. The while construct takes care of that. It continues executing the block (wrapped in braces) below it as long as the condition it was given holds. That condition is count <= 10, which means “count is less than or equal to 10”. We no longer have to create a temporary value and compare that to zero, which was just an uninteresting detail. Part of the power of programming languages is that they can take care of uninteresting details for us.

这个版本给了我们更多的改进。最重要的是,不再需要指定程序来回跳转的方式。While 构造负责这个。只要给定的条件成立,它就会继续执行下面的块(包装在大括号中)。这个条件是 count < = 10,意思是“ count 小于或等于10”。我们不再需要创建一个临时值并将其与零进行比较,这只是一个无趣的细节。编程语言的部分力量在于它们可以为我们处理无趣的细节。

At the end of the program, after the while construct has finished, the console.log operation is used to write out the result.

在程序结束时,while 构造完成后,使用 console.log 操作写出结果。

Finally, here is what the program could look like if we happened to have the convenient operations range and sum available, which respectively create a collection of numbers within a range and compute the sum of a collection of numbers:


[](#c_yYSVMpVrKE)console.log(sum(range(1, 10)));
// → 55

The moral of this story is that the same program can be expressed in both long and short, unreadable and readable ways. The first version of the program was extremely obscure, whereas this last one is almost English: log the sum of the range of numbers from 1 to 10. (We will see in later chapters how to define operations like sum and range.)

这个故事的寓意是,同一个程序可以用长或短、不可读和可读的方式来表达。程序的第一个版本非常模糊,而最后一个版本几乎是英文的: 记录从1到10的数字范围的和。(我们将在后面的章节中看到如何定义像 sum 和 range 这样的操作。)

A good programming language helps the programmer by allowing them to talk about the actions that the computer has to perform on a higher level. It helps omit details, provides convenient building blocks (such as while and console.log), allows you to define your own building blocks (such as sum and range), and makes those blocks easy to compose.

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

What is JavaScript? 什么是 JavaScript?

JavaScript was introduced in 1995 as a way to add programs to web pages in the Netscape Navigator browser. The language has since been adopted by all other major graphical web browsers. It has made modern web applications possible—applications with which you can interact directly without doing a page reload for every action. JavaScript is also used in more traditional websites to provide various forms of interactivity and cleverness.

1995年引入 JavaScript,作为在网景导航者浏览器中向网页添加程序的一种方式。这种语言已经被其他主要的图形浏览器所采用。它使现代网络应用成为可能ーー应用程序可以直接与之交互,而不必为每个操作重新加载页面。JavaScript 也被用于更传统的网站,以提供各种形式的交互性和巧妙性。

It is important to note that JavaScript has almost nothing to do with the programming language named Java. The similar name was inspired by marketing considerations rather than good judgment. When JavaScript was being introduced, the Java language was being heavily marketed and was gaining popularity. Someone thought it was a good idea to try to ride along on this success. Now we are stuck with the name.

值得注意的是,JavaScript 与名为 Java 的编程语言几乎没有任何关系。这个类似的名字是出于市场考虑,而不是出于良好的判断。当 JavaScript 被引入的时候,Java 语言正在被大力推销,并且越来越流行。有人认为,试图在这种成功上乘风破浪是一个好主意。现在我们只能用这个名字了。

After its adoption outside of Netscape, a standard document was written to describe the way the JavaScript language should work so that the various pieces of software that claimed to support JavaScript were actually talking about the same language. This is called the ECMAScript standard, after the Ecma International organization that did the standardization. In practice, the terms ECMAScript and JavaScript can be used interchangeably—they are two names for the same language.

在网景公司之外,一个标准的文档被用来描述 JavaScript 语言应该如何工作,以至于各种声称支持 JavaScript 的软件实际上是在谈论同一种语言。这就是所谓的 ECMAScript 标准,以 Ecma国际标准化组织的名字命名。实际上,ECMAScript 和 JavaScript 这两个术语可以互换使用ーー它们是同一种语言的两个名称。

There are those who will say terrible things about JavaScript. Many of these things are true. When I was required to write something in JavaScript for the first time, I quickly came to despise it. It would accept almost anything I typed but interpret it in a way that was completely different from what I meant. This had a lot to do with the fact that I did not have a clue what I was doing, of course, but there is a real issue here: JavaScript is ridiculously liberal in what it allows. The idea behind this design was that it would make programming in JavaScript easier for beginners. In actuality, it mostly makes finding problems in your programs harder because the system will not point them out to you.

有些人会说 JavaScript 的坏话。这些事情很多都是真的。当我第一次被要求用 JavaScript 写东西的时候,我很快就开始鄙视它。它几乎可以接受我输入的任何内容,但解释它的方式与我的意思完全不同。当然,这很大程度上是因为我不知道自己在做什么,但是这里有一个真正的问题: JavaScript 在允许的事情上是荒谬的自由。这个设计背后的想法是让初学者更容易用 JavaScript 编程。实际上,这主要使得在程序中发现问题变得更加困难,因为系统不会指出这些问题。

This flexibility also has its advantages, though. It leaves space for a lot of techniques that are impossible in more rigid languages, and as you will see (for example in Chapter 10), it can be used to overcome some of JavaScript’s shortcomings. After learning the language properly and working with it for a while, I have learned to actually like JavaScript.

不过,这种灵活性也有其优势。它为许多技术留下了空间,而这些技术在更严格的语言中是不可能的,正如你将看到的(例如在第10章) ,它可以用来克服 JavaScript 的一些缺点。在正确地学习这门语言并使用它一段时间之后,我已经学会了真正喜欢 JavaScript。

There have been several versions of JavaScript. ECMAScript version 3 was the widely supported version in the time of JavaScript’s ascent to dominance, roughly between 2000 and 2010. During this time, work was underway on an ambitious version 4, which planned a number of radical improvements and extensions to the language. Changing a living, widely used language in such a radical way turned out to be politically difficult, and work on the version 4 was abandoned in 2008, leading to a much less ambitious version 5, which made only some uncontroversial improvements, coming out in 2009. Then in 2015 version 6 came out, a major update that included some of the ideas planned for version 4. Since then we’ve had new, small updates every year.

已经有了几个版本的 JavaScript。3是 JavaScript 在2000年到2010年间占据统治地位的时候被广泛支持的版本。在此期间,一个雄心勃勃的版本4的工作正在进行中,该版本计划对语言进行一些根本性的改进和扩展。以如此激进的方式改变一种活的、被广泛使用的语言在政治上是困难的,并且关于版本4的工作在2008年被放弃,导致了一个雄心勃勃的版本5,在2009年出版,只做了一些没有争议的改进。然后在2015年版本6出来了,一个重大的更新,包括一些想法计划在版本4。从那时起,我们每年都有新的、小规模的更新。

The fact that the language is evolving means that browsers have to constantly keep up, and if you’re using an older browser, it may not support every feature. The language designers are careful to not make any changes that could break existing programs, so new browsers can still run old programs. In this book, I’m using the 2017 version of JavaScript.

语言不断发展的事实意味着浏览器必须不断跟上,如果你使用的是老版本的浏览器,它可能不会支持所有的功能。语言设计者小心翼翼地避免做出任何可能破坏现有程序的更改,因此新的浏览器仍然可以运行旧程序。在这本书中,我使用了2017年版本的 JavaScript。

Web browsers are not the only platforms on which JavaScript is used. Some databases, such as MongoDB and CouchDB, use JavaScript as their scripting and query language. Several platforms for desktop and server programming, most notably the Node.js project (the subject of Chapter 20), provide an environment for programming JavaScript outside of the browser.

浏览器并不是使用 JavaScript 的唯一平台。有些数据库,比如 MongoDB 和 CouchDB,使用 JavaScript 作为脚本和查询语言。桌面和服务器编程的一些平台,尤其是 Node.js 项目(第20章的主题) ,为浏览器之外的 JavaScript 编程提供了一个环境。

Code, and what to do with it 代码,以及如何使用它

Code is the text that makes up programs. Most chapters in this book contain quite a lot of code. I believe reading code and writing code are indispensable parts of learning to program. Try to not just glance over the examples—read them attentively and understand them. This may be slow and confusing at first, but I promise that you’ll quickly get the hang of it. The same goes for the exercises. Don’t assume you understand them until you’ve actually written a working solution.


I recommend you try your solutions to exercises in an actual JavaScript interpreter. That way, you’ll get immediate feedback on whether what you are doing is working, and, I hope, you’ll be tempted to experiment and go beyond the exercises.

我建议您使用一个实际的 JavaScript 解释器来尝试您的解决方案。这样,你就可以立即得到反馈,知道你正在做的事情是否有效,而且,我希望,你会受到诱惑去尝试并超越这些练习。

When reading this book in your browser, you can edit (and run) all example programs by clicking them.


If you want to run the programs defined in this book outside of the book’s website, some care will be required. Many examples stand on their own and should work in any JavaScript environment. But code in later chapters is often written for a specific environment (the browser or Node.js) and can run only there. In addition, many chapters define bigger programs, and the pieces of code that appear in them depend on each other or on external files. The sandbox on the website provides links to Zip files containing all the scripts and data files necessary to run the code for a given chapter.

如果你想在本书网站之外运行本书中定义的程序,需要一定的注意。许多示例都是独立的,应该可以在任何 JavaScript 环境中工作。但后面章节中的代码通常是为特定的环境(浏览器或 Node.js)编写的,并且只能在那里运行。此外,许多章节定义了较大的程序,其中出现的代码片段相互依赖或依赖于外部文件。网站上的沙箱提供了到 Zip 文件的链接,其中包含运行给定章节的代码所需的所有脚本和数据文件。

Overview of this book 本书概述

This book contains roughly three parts. The first 12 chapters discuss the JavaScript language. The next seven chapters are about web browsers and the way JavaScript is used to program them. Finally, two chapters are devoted to Node.js, another environment to program JavaScript in.

这本书大致包括三个部分。前12章讨论 JavaScript 语言。接下来的七章是关于网络浏览器和 JavaScript 编程的方法。最后,有两章是关于 Node.js 的,这是另一个 JavaScript 编程环境。

Throughout the book, there are five project chapters, which describe larger example programs to give you a taste of actual programming. In order of appearance, we will work through building a delivery robot, a programming language, a platform game, a pixel paint program, and a dynamic website.


The language part of the book starts with four chapters that introduce the basic structure of the JavaScript language. They introduce control structures (such as the while word you saw in this introduction), functions (writing your own building blocks), and data structures. After these, you will be able to write basic programs. Next, Chapters 5 and 6 introduce techniques to use functions and objects to write more abstract code and keep complexity under control.

本书的语言部分从介绍 JavaScript 语言的基本结构的四个章节开始。它们引入了控制结构(例如,您在本介绍中看到的 while 单词)、函数(编写自己的构建块)和数据结构。在这些之后,你将能够编写基本的程序。接下来,第5章和第6章介绍了使用函数和对象来编写更抽象的代码和控制复杂性的技术。

After a first project chapter, the language part of the book continues with chapters on error handling and bug fixing, regular expressions (an important tool for working with text), modularity (another defense against complexity), and asynchronous programming (dealing with events that take time). The second project chapter concludes the first part of the book.

在第一个项目章节之后,本书的语言部分继续讲述错误处理和 bug 修复、正则表达式(处理文本的重要工具)、模块化(对复杂性的另一种防御)和异步编程(处理需要时间的事件)。第二章是本书第一部分的总结。

The second part, Chapters 13 to 19, describes the tools that browser JavaScript has access to. You’ll learn to display things on the screen (Chapters 14 and 17), respond to user input (Chapter 15), and communicate over the network (Chapter 18). There are again two project chapters in this part.

第二部分,第13到19章,描述了 JavaScript 浏览器可以访问的工具。你将学习在屏幕上显示事物(第14章和第17章) ,响应用户输入(第15章) ,并通过网络进行通信(第18章)。在这一部分中还有两个项目章节。

After that, Chapter 20 describes Node.js, and Chapter 21 builds a small website using that tool.

在此之后,第20章描述了 Node.js,第21章用这个工具建立了一个小型网站。

Typographic conventions 字体约定

In this book, text written in a monospaced font will represent elements of programs—sometimes they are self-sufficient fragments, and sometimes they just refer to part of a nearby program. Programs (of which you have already seen a few) are written as follows:


[](#c_5GjN2pXyt/)function factorial(n) {
  if (n == 0) {
    return 1;
  } else {
    return factorial(n - 1) * n;

Sometimes, to show the output that a program produces, the expected output is written after it, with two slashes and an arrow in front.


// → 40320

Good luck!


×拖拽到此处图片将完成下载 Drag and drop the image to complete the download