1
0
mirror of https://github.com/apachecn/eloquent-js-3e-zh.git synced 2025-05-23 20:02:20 +00:00
This commit is contained in:
wizardforcel 2018-04-30 14:26:49 +08:00
parent a056282212
commit 99955cf662
7 changed files with 629 additions and 70 deletions

141
2.md
View File

@ -10,18 +10,19 @@
>
> 部分参考了[《JavaScript 编程精解(第 2 版)》](https://book.douban.com/subject/26707144/)
> And my heart glows bright red under my filmy, translucent skin and they have to administer 10cc of JavaScript to get me to come back. (I respond well to toxins in the blood.) Man, that stuff will kick the peaches right out your gills!
>
> why《Why's (Poignant) Guide to Ruby》
在本章中,我们开始做一些实际上称为编程的事情。 我们将扩展我们对 JavaScript 语言的正空,超出我们目前所看到的名词和句子片断,直到我们可以表达有意义的散文。
![](img/2-0.jpg)
### 2.1 表达式和语句
在本章中,我们开始做一些实际上称为编程的事情。 我们将扩展我们对 JavaScript 语言的掌控,超出我们目前所看到的名词和句子片断,直到我们可以表达有意义的散文。
## 表达式和语句
在第 1 章中,我们为它们创建了值,并应用了运算符来获得新的值。 像这样创建值是任何 JavaScript 程序的主要内容。 但是,这种东西必须在更大的结构中构建,才能发挥作用。 这就是我们接下来要做的。
我们把产生值的操作的代码片段称为表达式。按照字面含义编写的值(比如22或“psychoanalysis”)都是一个表达式。而括号当中的表达式、使用二元运算符连接的表达式或使用一元运算符的表达式,仍然都是表达式。
我们把产生值的操作的代码片段称为表达式。按照字面含义编写的值(比如`22``"psychoanalysis"`)都是一个表达式。而括号当中的表达式、使用二元运算符连接的表达式或使用一元运算符的表达式,仍然都是表达式。
这展示了一部分基于语言的接口之美。 表达式可以包含其他表达式,其方式非常类似于人类语言的从句嵌套 - 从句可以包含它自己的从句,依此类推。 这允许我们构建描述任意复杂计算的表达式。
@ -36,17 +37,17 @@
不过,这是一个无用的程序。 表达式可以仅仅满足于产生一个值,然后可以由闭合的代码使用。 一个声明是独立存在的,所以它只有在影响到世界的时候才会成立。 它可以在屏幕上显示某些东西 - 这可以改变世界 - 或者它可以改变机器的内部状态,从而影响后面的语句。 这些变化被称为副作用。 前面例子中的语句仅仅产生值`1``true`,然后立即将它们扔掉。 这给世界没有留下什么印象。 当你运行这个程序时,什么都不会发生。
在某些情况下JavaScript允许您在语句结尾处省略分号。 在其他情况下,它必须在那里,否则下一行将被视为同一语句的一部分。 何时可以安全省略它的规则有点复杂且容易出错。 所以在本书中,每一个需要分号的语句都会有分号。 至少在你更了解省略分号的细节之前,我建议你也这样做。
在某些情况下JavaScript 允许您在语句结尾处省略分号。 在其他情况下,它必须在那里,否则下一行将被视为同一语句的一部分。 何时可以安全省略它的规则有点复杂且容易出错。 所以在本书中,每一个需要分号的语句都会有分号。 至少在你更了解省略分号的细节之前,我建议你也这样做。
### 2.2 绑定
## 绑定
程序如何保持内部状态? 它如何记住东西? 我们已经看到如何从旧值中产生新值,但这并没有改变旧值,新值必须立即使用,否则将会再度消失。 为了捕获和保存值JavaScript 提供了一种称为绑定或绑定的东西:
程序如何保持内部状态? 它如何记住东西? 我们已经看到如何从旧值中产生新值,但这并没有改变旧值,新值必须立即使用,否则将会再度消失。 为了捕获和保存值JavaScript 提供了一种称为绑定或变量的东西:
```
let caught = 5 * 5;
```
这是第二种语句。 关键字(_keyword_`let`表示这个句子打算定义一个绑定。 它后面跟着绑定的名称,如果我们想立即给它一个值,使用`=`运算符和一个表达式。
这是第二种语句。 关键字keyword`let`表示这个句子打算定义一个绑定。 它后面跟着绑定的名称,如果我们想立即给它一个值,使用`=`运算符和一个表达式。
前面的语句创建一个名为`caught`的绑定,并用它来捕获乘以`5 * 5`所产生的数字。
@ -80,7 +81,7 @@ console.log(luigisDebt);
// → 105
```
当你定义一个绑定而没有给它一个值时,触手没有任何东西可以捕获,所以它只能捕获空气。 如果你请求一个空绑定的值,你会得到`'undefined'`值。
当你定义一个绑定而没有给它一个值时,触手没有任何东西可以捕获,所以它只能捕获空气。 如果你请求一个空绑定的值,你会得到`undefined`值。
一个`let`语句可以同时定义多个绑定,定义必需用逗号分隔。
@ -101,9 +102,9 @@ console.log(greeting + name);
第一个`var`“variable”的简写是 JavaScript 2015 之前声明绑定的方式。 我们在下一章中,会讲到它与`let`的确切的不同之处。 现在,请记住它大部分都做同样的事情,但我们很少在本书中使用它,因为它有一些令人困惑的特性。
“const”这个词代表常量。 它定义了一个不变的绑定,只要它存在,它就指向相同的值。 这对于一些绑定很有用,它们向值提供一个名词,以便之后可以很容易地引用它。
`const`这个词代表常量。 它定义了一个不变的绑定,只要它存在,它就指向相同的值。 这对于一些绑定很有用,它们向值提供一个名词,以便之后可以很容易地引用它。
### 绑定名称
## 绑定名称
绑定名称可以是任何单词。 数字可以是绑定名称的一部分,例如`catch22`是一个有效的名称,但名称不能以数字开头。 绑定名称可能包含美元符号(`$`)或下划线(`_`),但不包含其他标点符号或特殊字符。
@ -119,25 +120,25 @@ switch this throw true try typeof var void while with yield
不要担心记住这些东西。 创建绑定时会产生意外的语法错误,请查看您是否尝试定义保留字。
### 2.4 环境
## 环境
给定时间中存在的绑定及其值的集合称为环境。 当一个程序启动时,这个环境不是空的。 它总是包含作为语言标准一部分的绑定,并且在大多数情况下,它还具有一些绑定,提供与周围系统交互的方式。 例如,在浏览器中,有一些功函数能可以与当前加载的网站交互并读取鼠标和键盘输入。
### 2.5 函数
## 函数
在默认环境中提供的许多值的类型为函数。 函数是包裹在值中的程序片段。 为了运行包裹的程序,可以将这些值应用于它们。 例如,在浏览器环境中,绑定`prompt`包含一函数,个显示一个小对话框,请求用户输入。 它是这样使用的:
```
prompt("Good morning!");
prompt("Enter passcode");
```
![](../Images/00043.jpeg)
![](img/2-1.png)
执行一个函数被称为调用或应用它invokecallapply。您可以通过在生成函数值的表达式之后放置括号来调用函数。 通常你会直接使用持有该函数的绑定名称。 括号之间的值被赋予函数内部的程序。 在这个例子中,`prompt`函数使用我们提供的字符串作为文本来显示在对话框中。 赋予函数的值称为参数。 不同的函数可能需要不同的数量或不同类型的参数。
`prompt`函数在现代 Web 编程中用处不大,主要是因为你无法控制所得对话框的外观,但可以在玩具程序和实验中有所帮助。
### 2.6 `console.log`函数
## `console.log`函数
在例子中,我使用`console.log`来输出值。 大多数 JavaScript 系统(包括所有现代 Web 浏览器和 Node.js都提供了`console.log`函数,将其参数写入一个文本输出设备。 在浏览器中,输出出现在 JavaScript 控制台中。 浏览器界面的这一部分在默认情况下是隐藏的,但大多数浏览器在您按 F12 或在 Mac 上按 Command-Option-I 时打开它。 如果这不起作用,请在菜单中搜索名为“开发人员工具”或类似的项目。
@ -151,7 +152,7 @@ console.log("the value of x is", x);
尽管绑定名称不能包含句号字符,但是`console.log`确实拥有。 这是因为`console.log`不是一个简单的绑定。 它实际上是一个表达式,它从`console`绑定所持有的值中检索`log`属性。 我们将在第 4 章中弄清楚这意味着什么。
### 2.7 返回值
## 返回值
显示对话框或将文字写入屏幕是一个副作用。 由于它们产生的副作用,很多函数都很有用。 函数也可能产生值,在这种情况下,他们不需要有副作用就有用。 例如,函数`Math.max`可以接受任意数量的参数并返回最大值。
@ -169,7 +170,7 @@ console.log(Math.min(2, 4) + 100);
我们会在下一章当中讲解如何编写自定义函数。
### 2.9 控制流
## 控制流
当你的程序包含多个语句时,这些语句就像是一个故事一样从上到下执行。 这个示例程序有两个语句。 第一个要求用户输入一个数字,第二个在第一个之后执行,显示该数字的平方。
@ -184,13 +185,13 @@ console.log("Your number is the square root of " +
以下是直线控制流程的相当简单的示意图:
![](../Images/00052.jpeg)
![](img/2-2.svg)
### 2.10 条件执行
## 条件执行
并非所有的程序都是直路。 例如,我们可能想创建一条分叉路,在那里该程序根据当前的情况采取适当的分支。 这被称为条件执行。
![](../Images/00053.jpeg)
![](img/2-3.svg)
在 JavaScript 中,条件执行使用`if`关键字创建。 在简单的情况下,当且仅当某些条件成立时,我们才希望执行一些代码。 例如,仅当输入实际上是一个数字时,我们可能打算显示输入的平方。
@ -215,7 +216,7 @@ if (1 + 1 == 2) console.log("It's true");
// → It's true
```
您通常不会只执行条件成立时代码,还会处理其他情况的代码。 该替代路径由图中的第二个箭头表示。 可以使用`else`关键字和`if`一起创建两个单独的替代执行路径。
您通常不会只执行条件成立时代码,还会处理其他情况的代码。 该替代路径由图中的第二个箭头表示。 可以一起使用`if``else`关键字,创建两个单独的替代执行路径。
```py
let theNumber = Number(prompt("Pick a number"));
@ -227,7 +228,7 @@ if (!Number.isNaN(theNumber)) {
}
```
如果我们需要执行的路径多于两条可以将多个if/else对链接在一起使用。如下所示例子
如果我们需要执行的路径多于两条,可以将多个`if/else`对链接在一起使用。如下所示例子:
```
let num = Number(prompt("Pick a number", "0"));
@ -241,15 +242,15 @@ if (num < 10) {
}
```
该程序首先会检查num是否小于10。如果条件成立则执行显示“Small”的这条路径如果不成立则选择else分支else分支自身包含了第二个if。如果第二个条件即num小于100成立且数字的范围在10到100之间则执行显示“Medium”的这条路径。如果上述条件均不满足则执行最后一条else分支路径。
该程序首先会检查`num`是否小于 10。如果条件成立则执行显示`"Small"`的这条路径;如果不成立,则选择`else`分支,`else`分支自身包含了第二个`if`。如果第二个条件即`num`小于 100 成立,且数字的范围在 10 到 100 之间,则执行显示`"Medium"`的这条路径。如果上述条件均不满足,则执行最后一条`else`分支路径。
这个程序的模式看起来像这样:
![](../Images/00057.jpeg)
![](img/2-4.svg)
### 2.11 `while``do`循环
## `while``do`循环
现考虑编写一个程序输出0到12之间的所有偶数。其中一种编写方式如下所示
现考虑编写一个程序,输出 0 12 之间的所有偶数。其中一种编写方式如下所示:
```
console.log(0);
@ -261,9 +262,9 @@ console.log(10);
console.log(12);
```
该程序确实可以工作但编程的目的在于减少工作量而非增加。如果我们需要小于1000的偶数上面的方式是不可行的。我们现在所需的是重复执行某些代码的方法我们将这种控制流程称为循环。
该程序确实可以工作,但编程的目的在于减少工作量,而非增加。如果我们需要小于 1000 的偶数,上面的方式是不可行的。我们现在所需的是重复执行某些代码的方法,我们将这种控制流程称为循环。
![](http://eloquentjavascript.net/2nd_edition//img/controlflow-loop.svg)
![](img/2-5.svg)
我们可以使用循环控制流来让程序执行回到之前的某个位置,并根据程序状态循环执行代码。如果我们在循环中使用一个绑定计数,那么就可以按照如下方式编写代码:
@ -278,7 +279,7 @@ while (number <= 12) {
// … etcetera
```
循环语句以关键字while开头。在关键字while后紧跟一个用括号括起来的表达式括号后紧跟一条语句这种形式与if语句类似。只要表达式产生的值转换为布尔值后为`true`,该循环会持续进入括号后面的语句。
循环语句以关键字`while`开头。在关键字`while`后紧跟一个用括号括起来的表达式,括号后紧跟一条语句,这种形式与`if`语句类似。只要表达式产生的值转换为布尔值后为`true`,该循环会持续进入括号后面的语句。
`number`绑定演示了绑定可以跟踪程序进度的方式。 每次循环重复时,`number`的值都比以前的值多 2。 在每次重复开始时,将其与数字 12 进行比较来决定程序的工作是否完成。
@ -308,9 +309,9 @@ do {
console.log(yourName);
```
这个程序会强制你输入一个名字。 它会一再询问,直到它得到的东西不是空字符串。 `!`运算符会将值转换为布尔类型再取反,除了`""`之外的所有字符串都转换为“true”。 这意味着循环持续进行,直到您提供了非空名称。
这个程序会强制你输入一个名字。 它会一再询问,直到它得到的东西不是空字符串。 `!`运算符会将值转换为布尔类型再取反,除了`""`之外的所有字符串都转换为`true`。 这意味着循环持续进行,直到您提供了非空名称。
### 2.12 代码缩进
## 代码缩进
在这些例子中,我一直在语句前添加空格,它们是一些大型语句的一部分。 这些都不是必需的 - 没有它们,计算机也会接受该程序。 实际上,即使是程序中的换行符也是可选的。 如果你喜欢,你可以将程序编写为很长的一行。
@ -327,7 +328,7 @@ if (false != true) {
大多数代码编辑器程序(包括本书中的那个)将通过自动缩进新行来提供帮助。
### 2.13 `for`循环
## `for`循环
许多循环遵循`while`示例中看到的规律。 首先,创建一个计数器绑定来跟踪循环的进度。 然后出现一个`while`循环,通常用一个测试表达式来检查计数器是否已达到其最终值。 在循环体的末尾,更新计数器来跟踪进度。
@ -343,9 +344,9 @@ for (let number = 0; number <= 12; number = number + 2)
该程序与之前的偶数打印示例完全等价。 唯一的变化是,所有与循环“状态”相关的语句,在`for`之后被组合在一起。
关键字for后面的括号中必须包含两个分号。第一个分号前面的是循环的初始化部分通常是定义一个绑定。第二部分则是判断循环是否继续进行的检查表达式。最后一部分则是用于每个循环迭代后更新状态的语句。绝大多数情况下for循环比while语句更简短清晰。
关键字`for`后面的括号中必须包含两个分号。第一个分号前面的是循环的初始化部分,通常是定义一个绑定。第二部分则是判断循环是否继续进行的检查表达式。最后一部分则是用于每个循环迭代后更新状态的语句。绝大多数情况下,`for`循环比`while`语句更简短清晰。
下面的代码中使用了for循环代替while循环来计算`2**10`
下面的代码中使用了`for`循环代替`while`循环,来计算`2**10`
```
var result = 1;
@ -355,11 +356,11 @@ console.log(result);
// → 1024
```
### 2.14 跳出循环
## 跳出循环
除了循环条件为false时循环会结束以外我们还可以使用一个特殊的break语句来立即跳出循环。
除了循环条件为`false`时循环会结束以外,我们还可以使用一个特殊的`break`语句来立即跳出循环。
下面的程序展示了break语句的用法。该程序的作用是找出第一个大于等于20且能被7整除的数字。
下面的程序展示了`break`语句的用法。该程序的作用是找出第一个大于等于 20 且能被 7 整除的数字。
```
for (let current = 20; ; current++) {
@ -370,17 +371,17 @@ for (let current = 20; ; current++) {
// → 21
```
我们可以使用余数运算符(%来判断一个数是否能被另一个数整除。如果可以整除则余数为0。
我们可以使用余数运算符(`%`)来判断一个数是否能被另一个数整除。如果可以整除,则余数为 0。
本例中的for语句省略了检查循环终止条件的表达式。这意味着除非执行了内部的break语句否则循环永远不会结束。
本例中的`for`语句省略了检查循环终止条件的表达式。这意味着除非执行了内部的`break`语句,否则循环永远不会结束。
如果你要删除这个`break`语句,或者你不小心写了一个总是产生`true`的结束条件,你的程序就会陷入死循环中。 死在无限循环中的程序永远不会完成运行,这通常是一件坏事。
如果你要删除这个`break`语句,或者你不小心写了一个总是产生`true`的结束条件,你的程序就会陷入死循环中。 死循环中的程序永远不会完成运行,这通常是一件坏事。
> 如果您在(英文版)这些页面的其中一个示例中创建;额死限循环,则通常会询问您是否要在几秒钟后停止该脚本。 如果失败了,您将不得不关闭您正在处理的选项卡,或者在某些浏览器中关闭整个浏览器,以便恢复。
> 如果您在(英文版)这些页面的其中一个示例中创建死限循环,则通常会询问您是否要在几秒钟后停止该脚本。 如果失败了,您将不得不关闭您正在处理的选项卡,或者在某些浏览器中关闭整个浏览器,以便恢复。
continue关键字与break类似也会对循环执行过程产生影响。循环体中的continue语句可以跳出循环体并进入下一轮循环迭代。
`continue`关键字与`break`类似,也会对循环执行过程产生影响。循环体中的`continue`语句可以跳出循环体,并进入下一轮循环迭代。
### 2.15 更新绑定的简便方法
## 更新绑定的简便方法
程序经常需要根据绑定的原值进行计算并更新值,特别是在循环过程中,这种情况更加常见。
@ -388,13 +389,13 @@ continue关键字与break类似也会对循环执行过程产生影响。循
counter = counter + 1;
```
JavaScript提供了一种简便写法
JavaScript 提供了一种简便写法:
```
counter += 1;
```
JavaScript还为其他运算符提供了类似的简便方法比如result*=2可以将result变为原来的两倍而counter-=1可以将counter减1。
JavaScript 还为其他运算符提供了类似的简便方法,比如`result*=2`可以将`result`变为原来的两倍,而`counter-=1`可以将`counter` 1。
这样可以稍微简化我们的计数示例代码。
@ -403,9 +404,9 @@ for (let number = 0; number <= 12; number += 2)
console.log(number);
```
对于counter+=1和counter-=1还可以进一步简化代码counter+=1可以修改为counter++counter-=1可以修改为counter--。
对于`counter+=1``counter-=1`,还可以进一步简化代码,`counter+=1`可以修改为`counter++``counter-=1`可以修改为`counter--`
### 2.16 switch条件分支
## `switch`条件分支
我们很少会编写如下所示的代码。
@ -436,7 +437,7 @@ switch (prompt("What is the weather like?")) {
你可以在`switch`打开的块内放置任意数量的`case`标签。 程序会在对应向`switch`提供的值的标签处开始执行,或者如果没有找到匹配值,则在`default`处开始。 甚至跨越了其他标签,它也会继续执行,直到达到了`break`声明。 在某些情况下,例如在示例中的`"sunny"`的情况下,这可以用来在不同情况下共享一些代码(它建议在晴天和多云天气外出)。 但要小心 - 很容易忘记这样的`break`,这会导致程序执行你不想执行的代码。
### 2.17 大写
## 大写
绑定名中不能包含空格,但很多时候使用多个单词有助于清晰表达绑定的实际用途。当绑定名中包含多个单词时可以选择多种写法,以下是可以选择的几种绑定名书写方式:
@ -451,11 +452,11 @@ fuzzyLittleTurtle
在极少数情况下绑定名首字母也会大写比如Number函数。这种方式用来表示该函数是构造函数。我们会在第6章详细讲解构造函数的概念。现在我们没有必要纠结于表面上的风格不一致性。
### 2.18 注释
## 注释
通常,原始代码并不能传达你让一个程序传达给读者的所有信息,或者它以神秘的方式传达信息,人们可能不了解它。 在其他时候,你可能只想包含一些相关的想法,作为你程序的一部分。 这是注释的用途。
注释是程序中的一段文本而在程序执行时计算机会完全忽略掉这些文本。JavaScript中编写注释有两种方法写单行注释时使用两个斜杠字符开头并在后面添加文本注释。
注释是程序中的一段文本而在程序执行时计算机会完全忽略掉这些文本。JavaScript 中编写注释有两种方法,写单行注释时,使用两个斜杠字符开头,并在后面添加文本注释。
```
let accountBalance = calculateBalance(account);
@ -468,7 +469,7 @@ addToReport(accountBalance, report);
// It's a little valley, foaming like light in a glass.
```
`//`注释只能到行尾。 `/*``*/`之间的一段文本将被忽略,不管它是否包含换行符。 这对添加文件或程序块的信息块很有用。
`//`注释只能到行尾。 `/*``*/`之间的一段文本将被忽略,不管它是否包含换行符。 这对添加文件或程序块的信息块很有用。
```
/*
@ -481,37 +482,37 @@ addToReport(accountBalance, report);
const myNumber = 11213;
```
### 2.19 本章小结
## 本章小结
在本章中,我们学习并了解了程序由语句组成,而每条语句又有可能包含了更多语句。在语句中往往包含了表达式,而表达式还可以由更小的表达式组成。
程序中的语句按顺序编写并从上到下执行。你可以使用条件语句if、else和switch或循环语句while、do和for来改变程序的控制流。
程序中的语句按顺序编写,并从上到下执行。你可以使用条件语句(`if``else``switch`)或循环语句(`while``do``for`)来改变程序的控制流。
绑定可以用来保存任何数据并用一个绑定名对其引用。而且在记录你的程序执行状态时十分有用。环境是一组定义好的绑定集合。JavaScript的运行环境中总会包含一系列有用的标准绑定。
绑定可以用来保存任何数据并用一个绑定名对其引用。而且在记录你的程序执行状态时十分有用。环境是一组定义好的绑定集合。JavaScript 的运行环境中总会包含一系列有用的标准绑定。
函数是一种特殊的值,用于封装一段程序。你可以通过functionName参数1参数2这种写法来调用函数。函数调用可以是一个表达式,也可以用于生成一个值。
函数是一种特殊的值,用于封装一段程序。你可以通过`functionName(arg1, arg2`这种写法来调用函数。函数调用可以是一个表达式,也可以用于生成一个值。
### 2.20 习题
## 习题
如果你不清楚在哪里可以找到习题的提示,请参考本书的简介部分。
每个练习都以问题描述开始。 阅读并尝试解决这个练习。 如果遇到问题,请考虑阅读练习后的提示。 纸质书不包含练习的完整解决方案,但您可以在 [eloquentjavascript.net/code](https://eloquentjavascript.net/code#2) 上在线查找它们。 如果你想从练习中学到一些东西,我建议仅在你解决了这个练习之后,或者至少在你努力了很长时间而感到头疼之后,再看看这些解决方案。
每个练习都以问题描述开始。 阅读并尝试解决这个练习。 如果遇到问题,请考虑阅读练习后的提示。 书不包含练习的完整解决方案,但您可以在 [eloquentjavascript.net/code](https://eloquentjavascript.net/code#2) 上在线查找它们。 如果你想从练习中学到一些东西,我建议仅在你解决了这个练习之后,或者至少在你努力了很长时间而感到头疼之后,再看看这些解决方案。
#### 2.20.1 LoopingaTriangle
### LoopingaTriangle
编写一个循环调用7次console.log函数打印出如下的三角形
编写一个循环,调用 7 `console.log`函数,打印出如下的三角形:
```
#
##
##
###
###
####
#####
######
#######
```
这里给出一个小技巧,在字符串后加上.length可以获取字符串的长度。
这里给出一个小技巧,在字符串后加上`.length`可以获取字符串的长度。
```
let abc = "abc";
@ -519,19 +520,19 @@ console.log(abc.length);
// → 3
```
#### 2.20.2 FizzBuzz
### FizzBuzz
编写一个程序使用console.log打印出从1到100的所有数字。不过有两种例外情况当数字能被3整除时不打印数字而打印“Fizz”。当数字能被5整除时但不能被3整除不打印数字而打印“Buzz”
编写一个程序,使用`console.log`打印出从 1 100 的所有数字。不过有两种例外情况:当数字能被 3 整除时,不打印数字,而打印`"Fizz"`。当数字能被 5 整除时(但不能被 3 整除),不打印数字,而打印`"Buzz"`
当以上程序可以正确运行后,请修改你的程序,让程序在遇到能同时被3与5整除的数字时打印出“FizzBuzz”
当以上程序可以正确运行后,请修改你的程序,让程序在遇到能同时被 3 与 5 整除的数字时,打印出`"FizzBuzz"`
(这实际上是一个面试问题,据说剔除了很大一部分程序员候选人,所以如果你解决了这个问题,你的劳动力市场价值就会上升。)
#### 2.20.3 棋盘
### 棋盘
编写一个程序创建一个字符串用于表示8×8的网格并使用换行符分隔行。网格中的每个位置可以是空格或字符“#”。这些字符组成了一张棋盘。
编写一个程序,创建一个字符串,用于表示`8×8`的网格,并使用换行符分隔行。网格中的每个位置可以是空格或字符`"#"`。这些字符组成了一张棋盘。
将字符串传递给console.log将会输出以下结果
将字符串传递给`console.log`将会输出以下结果:
```
# # # #
@ -544,4 +545,4 @@ console.log(abc.length);
# # # #
```
当程序可以产生这样的输出后请定义绑定size=8并修改程序使程序可以处理任意尺寸长宽由size确定的棋盘并输出给定宽度和高度的网格。
当程序可以产生这样的输出后,请定义绑定`size=8`,并修改程序,使程序可以处理任意尺寸(长宽由`size`确定)的棋盘,并输出给定宽度和高度的网格。

BIN
img/2-0.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
img/2-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

81
img/2-2.svg Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="204.48096"
height="19.999929"
id="svg3216"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="New document 8">
<defs
id="defs3218">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible">
<path
id="path3774"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="156.78125"
inkscape:cy="-138.56231"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1600"
inkscape:window-height="875"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata3221">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-218.21875,-373.79994)">
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m 218.236,384.24914 190.41375,0"
id="path5135"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

155
img/2-3.svg Normal file
View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="205.10103"
height="85.750778"
id="svg3283"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="New document 11">
<defs
id="defs3285">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible">
<path
id="path3774"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="marker3266"
style="overflow:visible">
<path
id="path3268"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="marker3270"
style="overflow:visible">
<path
id="path3272"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="marker3274"
style="overflow:visible">
<path
id="path3276"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="1288.581"
inkscape:cy="-271.41478"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1600"
inkscape:window-height="875"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0" />
<metadata
id="metadata3288">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(913.58095,-175.19662)">
<g
id="g3322"
transform="matrix(0,-1,1,0,-1032.3622,-596.20924)">
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m -815.78349,118.91917 1.01015,27.77919"
id="path4943"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m -807.70227,168.41664 c 0,0 67.6802,38.3858 7.07106,95.9645"
id="path5139"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path5141"
d="m -813.76319,274.48267 1.01015,35.35534"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path5159"
d="m -820.86915,168.41664 c 0,0 -67.68021,38.3858 -7.07106,95.9645"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
<path
transform="translate(-888.97485,115.42425)"
d="m 80.307123,50.755318 c 0,3.347351 -2.713564,6.060915 -6.060915,6.060915 -3.347351,0 -6.060915,-2.713564 -6.060915,-6.060915 0,-3.347351 2.713564,-6.060915 6.060915,-6.060915 3.347351,0 6.060915,2.713564 6.060915,6.060915 z"
sodipodi:ry="6.060915"
sodipodi:rx="6.060915"
sodipodi:cy="50.755318"
sodipodi:cx="74.246208"
id="path3001"
style="fill:#ff0000;fill-opacity:1;stroke:none"
sodipodi:type="arc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

175
img/2-4.svg Normal file
View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="238.24316"
height="104.35892"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="controlflow-nested-else.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible">
<path
id="path3774"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible">
<path
id="path3786"
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6,-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible">
<path
id="path3768"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3762"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="182.61224"
inkscape:cy="45.356254"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1600"
inkscape:window-height="875"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="3"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-222.69525,-394.46429)">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4943"
d="m 226.69525,431.70744 27.77919,1.01015"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path5139"
d="m 274.76415,441.21724 c 2.14286,43.57143 36.60008,44.46591 47.39307,47.42819"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m 411.18732,433.72774 35.35534,1.01015"
id="path5141"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m 278.69272,425.19321 c 0,0 60.8858,-56.96593 122.75021,-4.57106"
id="path5159"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:type="arc"
style="fill:#ff0000;fill-opacity:1;stroke:none"
id="path3001"
sodipodi:cx="74.246208"
sodipodi:cy="50.755318"
sodipodi:rx="6.060915"
sodipodi:ry="6.060915"
d="m 80.307123,50.755318 a 6.060915,6.060915 0 1 1 -12.12183,0 6.060915,6.060915 0 1 1 12.12183,0 z"
transform="matrix(0,1,1,0,223.20033,358.51608)" />
<path
transform="matrix(0,1,1,0,291.77176,418.51608)"
d="m 80.307123,50.755318 a 6.060915,6.060915 0 1 1 -12.12183,0 6.060915,6.060915 0 1 1 12.12183,0 z"
sodipodi:ry="6.060915"
sodipodi:rx="6.060915"
sodipodi:cy="50.755318"
sodipodi:cx="74.246208"
id="path3002"
style="fill:#ff0000;fill-opacity:1;stroke:none"
sodipodi:type="arc" />
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m 341.54987,484.43152 c 0,0 0.96327,-38.82118 55.9645,-46.85751"
id="path3004"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3006"
d="m 350.83558,490.14581 c 24.92879,-3.90484 44.71588,-30.84607 52.03593,-41.14323"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

147
img/2-5.svg Normal file
View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="206.31815"
height="72.428215"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="controlflow-loop.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Send"
orient="auto"
refY="0"
refX="0"
id="Arrow1Send"
style="overflow:visible">
<path
id="path3774"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Mend"
style="overflow:visible">
<path
id="path3786"
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6,-0.6)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible">
<path
id="path3768"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3762"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="30.225462"
inkscape:cy="52.400366"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1600"
inkscape:window-height="875"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-376.5106,-433.43911)">
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path5161"
d="m 478.22234,451.00514 c 29.28572,23.75 27.61731,51.59627 -8.71166,51.57646 -36.44966,-0.0199 -18.10635,-25.27225 -9.3957,-39.5054"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
<path
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)"
d="m 379.43917,445.98075 73.1512,-1.01015"
id="path3003"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3005"
d="m 482.59676,443.96045 87.76125,-1.01015"
style="fill:none;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Send)" />
<path
transform="matrix(0,-1,1,0,422.09693,518.66704)"
d="m 80.307123,50.755318 c 0,3.347351 -2.713564,6.060915 -6.060915,6.060915 -3.347351,0 -6.060915,-2.713564 -6.060915,-6.060915 0,-3.347351 2.713564,-6.060915 6.060915,-6.060915 3.347351,0 6.060915,2.713564 6.060915,6.060915 z"
sodipodi:ry="6.060915"
sodipodi:rx="6.060915"
sodipodi:cy="50.755318"
sodipodi:cx="74.246208"
id="path3004"
style="fill:#ff0000;fill-opacity:1;stroke:none"
sodipodi:type="arc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB