Merge pull request #248 from CLDXiang/translate-zh-cn-ch-2

Translate Ch. 2 into Simplified Chinese
This commit is contained in:
Jen Looper
2021-04-22 11:13:28 -04:00
committed by GitHub
12 changed files with 787 additions and 4 deletions

View File

@@ -7,5 +7,5 @@
## 评价表 ## 评价表
| 优秀 | 良好 | 尚可进步 | | 优秀 | 良好 | 尚可进步 |
| --- | --- | -- | | --- | --- | --- |
| 解释了 Web 开发者为什么需要这些工具 | 解释了开发者如何使用这些工具,但却没有解释为什么需要它们 | 既没有解释为什么使用这些工具,也没有给出使用它们的方法 | | 解释了 Web 开发者为什么需要这些工具 | 解释了开发者如何使用这些工具,但却没有解释为什么需要它们 | 既没有解释为什么使用这些工具,也没有给出使用它们的方法 |

View File

@@ -6,6 +6,6 @@
## 评价表 ## 评价表
| 标准 | 优秀 | 良好 | 尚可进步 | | 指标 | 优秀 | 良好 | 尚可进步 |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | --------------------------- | | --- | --- | --- | --- |
| 书面报告 | 解释了这个网站做得不好的地方,将 Lighthouse 报告打印为 PDF 文件,至少十点可改进之处,每点详细说明了改进策略 | 缺少上述 20% 内容 | 缺少上述 50% 内容 | | 书面报告 | 解释了这个网站做得不好的地方,将 Lighthouse 报告打印为 PDF 文件,至少十点可改进之处,每点详细说明了改进策略 | 缺少上述 20% 内容 | 缺少上述 50% 内容 |

View File

@@ -8,7 +8,7 @@
2. [GitHub 基础知识](../2-github-basics/translations/README.zh-cn.md) 2. [GitHub 基础知识](../2-github-basics/translations/README.zh-cn.md)
3. [无障碍性基础知识](../3-accessibility/translations/README.zh-cn.md) 3. [无障碍性基础知识](../3-accessibility/translations/README.zh-cn.md)
### 参考 ### 鸣谢
无障碍性基础知识由 [Christopher Harrison](https://twitter.com/geektrainer) 用 ♥️ 编写 无障碍性基础知识由 [Christopher Harrison](https://twitter.com/geektrainer) 用 ♥️ 编写

View File

@@ -0,0 +1,195 @@
# JavaScript 基础:数据类型
![JavaScript Basics - Data types](/sketchnotes/webdev101-js-datatypes.png)
> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac)
## 课前小测
[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/7?loc=zh_cn)
这节课将会介绍 JavaScript 的基础知识,正是它为网页提供了可交互性。
[![Data types in JavaScript](https://img.youtube.com/vi/JNIXfGiDWM8/0.jpg)](https://youtube.com/watch?v=JNIXfGiDWM8 "JavaScript 中的数据类型")
让我们从它最基础的组成部分 —— “变量”和“数据类型”学起吧!
## 变量Variables
变量用于存储会在你的代码中被使用和被改变的值。
创建和**声明**变量的语句是:**[关键字] [变量名]**,其由两部分组成:
- **关键字Keyword**。关键字可以是 `let` 或者 `var`
> 注意,`let` 关键字在 ES6 标准才被引入,会给你的变量一个 _块级作用域block scope_。一般建议使用 `let` 而非 `var`。我们将会在未来的章节中深入介绍块级作用域。
- **变量名The variable name**。你可以自己给变量起个名字。
### 任务:使用变量
1. **声明一个变量**。让我们用 `let` 关键字声明一个变量:
```javascript
let myVariable;
```
`myVariable` 现在就被用 `let` 关键字声明好了,但目前还没有被赋予一个值。
1. **赋值**。使用 `=` 运算符跟上一个期望的值来将一个值存储到变量中。
```javascript
myVariable = 123;
```
> 注意:这节课中使用的 `=` 均意味着我们使用了一个“赋值运算符”,用于给变量设置一个值。它并不表示相等。
`myVariable` 现在就已经被用 123 这个值 _初始化了initialized_。
1. **重构语句**。将你的代码换位下面的语句:
```javascript
let myVariable = 123;
```
上面的写法被称为 _显式初始化explicit initialization_即在声明一个变量的同时为它赋予一个初始值。
1. **修改变量的值**。用下面的方式修改变量的值:
```javascript
myVariable = 321;
```
在变量声明之后,你可以在你代码中的任何地方通过 `=` 运算符跟上新的值来修改它的值。
✅ 亲手尝试一下!你现在就可以在浏览器里写 JavaScript 代码。打开一个浏览器窗口然后打开开发者工具。在控制台console中你可以看到一个命令提示符输入 `let myVariable = 123`,按下回车键,然后再输入 `myVariable`。会发生什么?你在之后的课程中会了解到更多相关概念。
## 常量Constants
声明和初始化一个常量和变量基本类似,只不过要用 `const` 关键字。常量一般会使用全大写字母的方式命名。
```javascript
const MY_VARIABLE = 123;
```
常量和变量很相似,但有两点区别:
- **必须有一个值**。常量必须被初始化,否则会在运行代码时报错。
- **引用Reference无法被修改**。初始化后变量的引用就无法再被修改,否则会在运行代码时报错。让我们看两个例子:
- **简单数值**。下方做法是不被允许的:
```javascript
const PI = 3;
PI = 4; // 报错
```
- **对象引用会受保护**。下方做法是不被允许的:
```javascript
const obj = { a: 3 };
obj = { b: 5 } // 报错
```
- **对象的值不会受保护**。下方做法**是**被允许的:
```javascript
const obj = { a: 3 };
obj.a = 5; // 允许
```
上例中你修改的是对象的值而非其引用本身,所以是允许的。
> 注意,`const` 意味着引用是没法被重新赋值的,但是它的值并非是 _不可变的immutable_你可以修改它的值特别是在假如它是诸如对象这样的复杂结构的情况下。
## 数据类型Data Types
变量可以可以存储许多不同类型的值,比如数字或者文本。这些值的各种类型被称为**数据类型**。数据类型是软件开发中重要的组成部分,因为它会有助于开发者决定代码编写和软件运行的方式。更重要的是,一些数据类型有着可以帮助转换或者附加额外信息给变量的独特特性。
✅ 数据类型有时也特指 JavaScript 基本类型primitives它们是这个语言提供的最底层的数据类型。JavaScript 有六种基本数据类型string、number、bigint、boolean、undefined 和 symbol。你认为 `'zebra'` 属于哪种数据类型?`0` 和 `true` 呢?
### 数值Numbers
在之前的部分中,`myVariable` 的值属于数值数据类型。
`let myVariable = 123;`
变量可以存储所有类型的数值,包括小数或者负数。数值也可以搭配算术运算符使用,将在[下一部分](#operators)介绍。
### 算术运算符Arithmetic Operators
有许多种可以用在算术功能的运算符,下面列出了一部分:
| 符号 | 描述 | 例子 |
| --- | --------------------------- | ------------------------- |
| `+` | **加法**:计算两个数的和 | `1 + 2 // 结果是 3` |
| `-` | **减法**:计算两个数的差 | `1 - 2 // 结果是 -1` |
| `*` | **乘法**:计算两个数的积 | `1 * 2 // 结果是 2` |
| `/` | **除法**:计算两个数的商 | `1 / 2 // 结果是 0.5` |
| `%` | **取余**:计算两个数相除的余数 | `1 % 2 // 结果是 1` |
✅ 亲手试试!在你的浏览器控制台中尝试一下算术运算。结果是否和你期望的相同?
### 字符串Strings
字符串是由单引号或双引号包围的字符集合。
- `'这是一个字符串'`
- `"这也是一个字符串"`
- `let myString = '这是一个存储在变量中的字符串值';`
记得用引号来书写字符串,否则 JavaScript 会误以为它是一个变量名。
### 格式化字符串
字符串是文本,自然会有格式化的需求。
要**连接concatenate**两个或更多字符串,或者说把它们结合到一起,可以用 `+` 运算符。
```javascript
let myString1 = "Hello";
let myString2 = "World";
myString1 + myString2 + "!"; //HelloWorld!
myString1 + " " + myString2 + "!"; //Hello World!
myString1 + ", " + myString2 + "!"; //Hello, World!
```
✅ 在 JavaScript 中,为什么 `1 + 1 = 2` 但 `'1' + '1' = 11`?仔细想想。如果是 `'1' + 1` 呢?
**模板字符串Template literals**是另一种格式化字符串的方式使用反引号backtick而非引号。 任何非纯文本的内容都要放到 `${ }` 占位符内,可以是任何可能是字符串的变量。
```javascript
let myString1 = "Hello";
let myString2 = "World";
`${myString1} ${myString2}!` //Hello World!
`${myString1}, ${myString2}!` //Hello, World!
```
两种方式都可以达到格式化字符串的目的,但是格式化字符串会保留所有的空格和换行。
✅ 你会在什么时候使用模板字符串?什么时候使用纯文本字符串?
### 布尔值Booleans
布尔值只可能是这两个值:`true` 或 `false`。布尔值可以用于决定特定条件被满足时该运行哪些代码。多数情况下,[运算符](#operators)都可以设置布尔值,你会常常看到或者自己写出一些被通过运算符初始化或更新为布尔值。
- `let myTrueBool = true`
- `let myFalseBool = false`
✅ 如果一个变量的计算结果是 `true`我们就把它称为“真值truthy”。一个有意思的事是在 JavaScript 中,[所有值都是真值除非它们被定义为假值falsy)](https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy)。
---
## 🚀 挑战
JavaScript 偶尔会因为其对于数据类型令人意外的处理方式而被人诟病。你可以对这些“陷阱”做一点调查,比如大小写敏感性带来的问题,在控制台中试试 `let age = 1; let Age = 2; age == Age`(结果是 `false`,为什么?)。你还能找到哪些陷阱?
## 课后小测
[课后小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/8?loc=zh_cn)
## 复习 & 自学
看看这个[JavaScript 练习列表](https://css-tricks.com/snippets/javascript/)并尝试其中一个。你学到了什么?
## 作业
[数据类型练习](assignment.zh-cn.md)

View File

@@ -0,0 +1,11 @@
# 数据类型练习
## 说明
想象你正在搭建一个购物车。写一个文档,描述一下为了完成你的购物之旅你可能会用到哪些数据类型。你是如何得出这些选择的?
## 评价表
| 指标 | 优秀 | 良好 | 尚可进步 |
| --- | --- | --- | --- |
| | 六种数据类型都被列出并且详细进行了说明,还说明了它们会被如何使用 | 举了四种数据类型 | 举了两种数据类型 |

View File

@@ -0,0 +1,195 @@
# JavaScript 基础:方法和函数
![JavaScript Basics - Functions](/sketchnotes/webdev101-js-functions.png)
> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac)
## 课前小测
[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/9?loc=zh_cn)
当我们思考如何去写代码的时候,我们总是希望确保自己的代码是可读的。尽管听起来有些违反直觉,代码被阅读的次数会远多于它被写下的次数。**函数function** 正是开发者的工具箱里用于确保代码可维护的一件利器。
[![Methods and Functions](https://img.youtube.com/vi/XgKsD6Zwvlc/0.jpg)](https://youtube.com/watch?v=XgKsD6Zwvlc "方法和函数")
> 点击上方图片来观看一个有方法和函数的视频。
## 函数Functions
本质上,函数就是一块我们可以按需执行的代码。这在我们需要多次执行同一个任务的场景下很有用,比起将逻辑复制到很多个位置(这会导致在以后很难去同时更新所有位置),我们可以将其集中在同一个位置,在需要这套逻辑被执行的任何时候都可以来调用它 —— 你甚至可以在其他的函数中调用函数!
合理命名一个函数同样是很重要的能力。尽管听起来微不足道,但函数命名相当于是一种给一部分代码写简易文档的快捷做法。可以用网页上按钮的标签来类比这件事,如果我点击了一个叫做“停止计时”的按钮,我能够很轻易地知道它可以用来停止一个时钟的运行。
## 创建和调用函数
函数的语法一般长这样:
```javascript
function nameOfFunction() { // 函数定义
// 函数定义 / 函数体
}
```
如果你想创建一个用来打招呼的函数,它可以是这样:
```javascript
function displayGreeting() {
console.log('Hello, world!');
}
```
如果想要调用call / invoke一个函数用函数的名称跟上 `()` 即可。值得注意的是函数定义在其调用位置之前或之后都是可以的JavaScript 编译器会替你找到函数定义的位置。
```javascript
// 调用我们的函数
displayGreeting();
```
> **注意:**有一类特殊的函数被称作**方法method**,你其实已经使用过它了!上面的示例中的 `console.log` 就是一个例子。方法和函数的区别在于,方法依附于一个对象上(比如例子中的 `console`),而函数是自由自在的。但你以后会看到很多开发者有时也会将这两个术语混用。
### 函数的最佳实践
这里有一些在你创建函数时可以牢记在心的最佳实践:
- 坚持使用描述性的命名,这样可以更容易知道这个函数是做什么的
- 使用**小驼峰命名法camelCasing**来组合单词(译注:小驼峰,即除了第一个单词首位小写外,其它单词都首位大写)
- 让你的函数专注于一件特定的任务
## 向函数传递信息
为了使函数可以更便于重复利用,你常会希望传递一些信息给它。考虑上面 `displayGreeting` 这个例子,它只会显示 **Hello, world!**,但它其实可以被创造得更加有用一些。如果我们想让它更加灵活一些,比如允许指定想要打招呼的人的名字,我们可以为函数添加一个**参数parameter / argument**。参数,就是传给函数的额外信息。
参数会列在函数定义这一部分,用括号括起来并且用逗号分隔,比如:
```javascript
function name(param, param2, param3) {
}
```
我们可以更新以下我们的 `displayGreeting` 来接收一个名字并将其显示出来。
```javascript
function displayGreeting(name) {
const message = `Hello, ${name}!`;
console.log(message);
}
```
当我们想要在调用函数时指定参数,将其放在括号中即可。
```javascript
displayGreeting('Christopher');
// 在运行时会显示 “Hello, Christopher!”
```
## 默认值Default values
我们可以通过为函数添加更多参数来使它更加灵活,但是如果我们并不希望每次调用都需要指定所有参数该怎么办?继续用我们的打招呼示例,我们可以让名字是必选的(我们需要知道该向谁打招呼),但打招呼的语句本身可以随意定制。如果有人不想自定义打招呼的语句,我们就会提供一个默认值(又称缺省值)。为了给参数提供一个默认值,写法和给变量赋值很像 —— `parameterName = 'defaultValue'`。完整例子如下:
```javascript
function displayGreeting(name, salutation='Hello') {
console.log(`${salutation}, ${name}`);
}
```
当我们调用函数时,可以自由决定是否要指定 `salutation` 的值。
```javascript
displayGreeting('Christopher');
// 显示 “Hello, Christopher”
displayGreeting('Christopher', 'Hi');
// 显示 “Hi, Christopher”
```
## 返回值Return values
目前为止我们创建的函数都只会输出到[控制台console](https://developer.mozilla.org/zh-CN/docs/Web/API/console)。有时这就是我们想要的效果,特别是当我们创建调用其他服务的函数时。但如果我想要创建一个辅助函数来计算一个值并且返回出去用在别处该怎么办?
我们可以用**返回值**来做到这件事。返回值由函数返回,并且可以像字面量(如字符串或数值)一样存储在一个变量中。
如果一个函数有返回值,就会在函数体中用到 `return` 关键字。`return` 关键字可以指定期望被返回的值或引用,就像下面这样:
```javascript
return myVariable;
```
我们可以创建一个函数来构造一个打招呼的消息,然后将这个消息的值返回给调用者
```javascript
function createGreetingMessage(name) {
const message = `Hello, ${name}`;
return message;
}
```
调用函数时可以将返回值存在变量里,和将一个静态值存入变量的办法一样(如 `const name = 'Christopher'`)。
```javascript
const greetingMessage = createGreetingMessage('Christopher');
```
## 将函数作为函数参数
在你的编程生涯中,你会遇到一些可以接受函数作为参数的函数。这个优雅的小技巧会经常被用到,比如我们不知道一些事会在什么时候发生或完成,但我们知道在那个时候需要执行一个操作作为响应的情况。
举个例子,对于 [setTimeout](https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout),其会开启一个计时器,在倒计时结束时执行代码。我们需要告诉它我们希望它执行什么代码。这听起来正是函数该做到的事!
如果你执行下方的代码,三秒后你就可以看到 **3 秒过去了** 这条消息。
```javascript
function displayDone() {
console.log('3 秒过去了');
}
// 计时器的时间单位是毫秒
setTimeout(displayDone, 3000);
```
### 匿名函数Anonymous functions
再回过头看看我们创建的函数,我们创建了一个名字只被使用了一次的函数。当我们的应用程序变得愈发复杂,我们会发现我们创建了大量只被调用了一次的函数。这样实在不太好,其实我们并不总是需要为函数提供一个名字!
当我们将一个函数作为参数传入时,我们可以绕过提前创建它的步骤,直接在参数的部分来创建它。我们还是使用相同的 `function` 关键字,只不过是将其作为一个参数来创建。
让我们将上面的代码用匿名函数重写一次:
```javascript
setTimeout(function() {
console.log('3 秒过去了');
}, 3000);
```
运行我们的新代码,你会注意到结果和之前完全一样。我们成功创建了一个函数,而不必给它命名!
### 箭头函数Fat arrow functions
在很多编程语言(包括 JavaScript中都有一种称为**箭头**arrow / fat arrow函数的快捷写法。它会用到一个特殊的 `=>` 标志,看起来就像一个箭头 —— 它的名字就是这么来的!使用 `=>`,我们就可以跳过 `keyword` 关键字。
让我们用箭头函数再一次重写上面的代码:
```javascript
setTimeout(() => {
console.log('3 秒过去了');
}, 3000);
```
### 何时使用上述每种策略
你现在已经见到了三种将函数作为参数传给另一个函数的写法,可能很好奇该在什么时候选用哪一种。如果你知道你会多次用到这个函数,就照常创建它。如果你只会在一处用到它,一般最好使用匿名函数。使用箭头函数还是传统的 `function` 语法取决于你自己,但你会注意到多数现代开发者更喜欢用 `=>`
---
## 🚀 挑战
你能用一句话清楚说明函数和方法的区别吗?试一试!
## 课后小测
[课后小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/10?loc=zh_cn)
## 复习 & 自学
箭头函数在代码库中正在被越来越多地使用,[多了解一下箭头函数](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)会非常有好处。试着写一个函数,然后用箭头函数语法重写它。
## 作业
[试玩函数](assignment.zh-cn.md)

View File

@@ -0,0 +1,13 @@
# 试玩函数
## 说明
创建一个会返回什么东西的函数,再创建一个不会返回任何东西的函数。
试试看让它们有多种参数,并且让其中一部分参数有默认值。
## 评价表
| 指标 | 优秀 | 良好 | 尚可进步 |
| --- | --- | --- | --- |
| | 给出了两个或更多运行良好的函数,并且有多种多样的参数 | 只有一个可以正常运行的函数,参数也不多 | 有 Bug |

View File

@@ -0,0 +1,177 @@
# JavaScript 基础:做出决定
![JavaScript Basics - Making decisions](/sketchnotes/webdev101-js-decisions.png)
> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac)
## 课前小测
[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/11?loc=zh_cn)
对你的代码运行方式做出决定并且控制它们的顺序可以让你的代码更加可复用和稳定。这节课会介绍 JavaScript 中控制数据流的语法以及其与布尔数据类型搭配使用时的重要性。
[![Making Decisions](https://img.youtube.com/vi/SxTp8j-fMMY/0.jpg)](https://youtube.com/watch?v=SxTp8j-fMMY "做出决定")
> 点击上方图片来观看一个有关做出决定的视频。
## 布尔值简要回顾
布尔值只有两个值:`true``false`。布尔值有助于决定在满足一定条件下应该运行哪些行的代码。
可以用如下方式将你的布尔变量设为真或假:
`let myTrueBool = true`
`let myFalseBool = false`
✅ 布尔值Booleans的命名来源于英国数学家、哲学家和逻辑学家 George Boole1815-1864
## 比较运算符Comparison Operators与布尔值
一些运算符可用于表示比较的结果(会以布尔值返回)。下面是一些常用的运算符:
| 符号 | 描述 | 示例 |
| --- | --- | --- |
| `<` | **小于**:比较两个值,如果左边的值小于右边的值则返回 `true` | `5 < 6 // true` |
| `<=` | **小于或等于**:比较两个值,如果左边的值小于或等于右边的值则返回 `true` | `5 <= 6 // true` |
| `>` | **大于**:比较两个值,如果左边的值大于右边的值则返回 `true` | `5 > 6 // false` |
| `>=` | **大于或等于**:比较两个值,如果左边的值大于或等于右边的值则返回 `true` | `5 >= 6 // false` |
| `===` | **严格等于**:比较两个值,如果左边的值等于右边的值**且**数据类型相同则返回 `true` | `5 === 6 // false` |
| `!==` | **不等于**:比较两个值,返回与“严格等于”运算结果相反的布尔值 | `5 !== 6 // true` |
✅ 在你的浏览器控制台中亲手写一些比较来验证你的知识。有任何让你感到意外的返回结果吗?
## If 语句
If 语句会在条件为真的情况下运行它的块中的代码。
```javascript
if (condition){
// 如果 condition 为 true这个块中的代码将会运行。
}
```
比较/逻辑运算符常被用于构造条件式。
```javascript
let currentMoney;
let laptopPrice;
if (currentMoney >= laptopPrice){
// 如果条件为 true这个块中的代码将会运行。
console.log("Getting a new laptop!");
}
```
## If..Else 语句
`else` 语句会在条件为假的情况下运行它块中的代码。它后面可以跟上一个 `if` 语句。
```javascript
let currentMoney;
let laptopPrice;
if (currentMoney >= laptopPrice){
// 如果条件为 true这个块中的代码将会运行。
console.log("Getting a new laptop!");
}
else{
// 如果条件为 false这个块中的代码将会运行。
console.log("Can't afford a new laptop, yet!");
}
```
✅ 通过在浏览器控制台运行上方和接下来的代码来检查你对它的理解是否正确。可以通过修改 currentMoney 和 laptopPrice 变量的值来尝试改变 `console.log()` 打印出的值。
## 逻辑运算符Logical Operators与布尔值
做出决定可能需要不止一次比较,可以用逻辑运算符将比较结果串在一起来产生一个布尔值。
| 符号 | 描述 | 示例 |
| --- | --- | --- |
| `&&` | **逻辑与AND**:比较两个布尔表达式,只有在两边**都是真**时返回真 | `(5 > 6) && (5 < 6 ) // 一边为假,另一边为真,返回假` |
| `\|\|` | **逻辑或OR**:比较两个布尔表达式,在至少一边为真时返回真 | `(5 > 6) \|\| (5 < 6) // 一边为假,另一边为真,返回真` |
| `!` | **逻辑非NOT**:返回与一个布尔表达式相反的布尔值 | `!(5 > 6) // 5 并不比 6 大,但 "!" 会返回真` |
## 用逻辑运算符来构造条件和决定
If...else 语句中,逻辑运算符可以用来构造条件。
```javascript
let currentMoney;
let laptopPrice;
let laptopDiscountPrice = laptopPrice - (laptopPrice * .20) // 打八折后的笔记本电脑价格
if (currentMoney >= laptopPrice || currentMoney >= laptopDiscountPrice){
// 如果条件为 true这个块中的代码将会运行。
console.log("Getting a new laptop!");
}
else {
// 如果条件为 false这个块中的代码将会运行。
console.log("Can't afford a new laptop, yet!");
}
```
### 取反运算符Negation operator
你现在已经了解到如何用 `if...else` 语句来创建条件逻辑。任何传入 `if` 的东西都需要计算出一个 true 或者 false。通过 `!` 运算符你可以将表达式 _取反_。就像这样:
```javascript
if (!condition) {
// 如果 condition 为 false 则运行
} else {
// 如果 condition 为 true 则运行
}
```
### 三元表达式Ternary expressions
`if...else` 并非表达决定逻辑的唯一方式,你也可以使用一个叫做三元运算符的东西。语法如下:
```javascript
let variable = condition ? <若为 true 则返回这个> : <若为 false 则返回这个>
```
下方是一个更具体的例子:
```javascript
let firstNumber = 20;
let secondNumber = 10
let biggestNumber = firstNumber > secondNumber ? firstNumber: secondNumber;
```
✅ 花一分钟多看几遍上方代码,你能想明白这些运算符是什么意思吗?
上方代码表示:
- 如果 `firstNumber` 大于 `secondNumber`
- 就将 `firstNumber` 赋值给 `biggestNumber`
- 否则将 `secondNumber` 赋值给 `biggestNumber`
三元表达式其实只是下方代码的一个简单写法:
```javascript
let biggestNumber;
if (firstNumber > secondNumber) {
biggestNumber = firstNumber;
} else {
biggestNumber = secondNumber;
}
```
---
## 🚀 挑战
用逻辑运算符写一个程序,然后用三元表达式重写它。你更喜欢哪种语法?
---
## 课后小测
[Post-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/12?loc=zh_cn)
## 复习 & 自学
在 [MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators) 上了解更多开发者可以使用的运算符。
试用一下由 Josh Comeau 制作的绝妙的[运算符查询器](https://joshwcomeau.com/operator-lookup/)
## 作业
[运算符](assignment.zh-cn.md)

View File

@@ -0,0 +1,40 @@
# 运算符
## 说明
玩转运算符。这里有一个你可以尝试去实现的程序的建议:
你有一群来自两种不同评分系统的学生。
### 第一种评分系统
一种评分系统的分数范围是 1-5其中 3 及以上代表合格。
### 第二种评分系统
另一种评分系统有这些分数:`A, A-, B, B-, C, C-`,其中 `A` 是最好的分数,`C` 是最低的合格分数。
### 任务
有下方数组 `allStudents`,表示所有学生和它们的分数,构造一个包含所有合格的学生的新数组 `studentWhoPass`
> 提示:可利用 for 循环、if...else 语句和比较运算符
```javascript
let allStudents = [
'A',
'B-',
1,
4,
5,
2
]
let studentsWhoPass = [];
```
## 评价表
| 指标 | 优秀 | 良好 | 尚可进步 |
| --- | --- | --- | --- |
| | 给出了完整解答 | 给出了部分解答 | 解答中存在 Bug |

View File

@@ -0,0 +1,125 @@
# JavaScript 基础:数组和循环
![JavaScript Basics - Arrays](/sketchnotes/webdev101-js-arrays.png)
> 涂鸦笔记作者:[Tomomi Imura](https://twitter.com/girlie_mac)
## 课前小测
[课前小测](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/13?loc=zh_cn)
这节课将会介绍 JavaScript 的基础知识,正是它为网页提供了可交互性。这节课中,你将学习数组和循环,它们会被用于操控数据。
[![Arrays and Loops](https://img.youtube.com/vi/Q_CRM2lXXBg/0.jpg)](https://youtube.com/watch?v=Q_CRM2lXXBg "数组和循环")
> 点击上方图片来观看一个有关数组和循环的视频。
## 数组Arrays
对于任何编程语言来说,使用数据都是很常见的工作,将数组组织在一个结构性的格式(比如数组)中则可以让这个工作更简单。通过使用数组,数据会被存放在一个类似列表的结构中。数组的一个主要优点是你可以将不同类型的数据存入同一个数组中。
✅ 数组在我们的生活中随处可见!你能想到一个现实生活中的数组的例子吗,比如一个太阳能板阵列?
数组的语法需要一对方括号。
`let myArray = [];`
这是一个空数组,但数组其实可以在声明时就存入一些数据。数组中的多项数据用逗号分隔。
`let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];`
数组中的值会被指定一个唯一的值,称为 **索引index**,它是一个整数,表示对应值在数组中的位置与数组开头的距离。在上方的例子中,字符串值 `"Chocolate"` 的索引就是 0`"Rocky Road"` 的索引是 4。可以用索引加上方括号来获取、改变或者插入数组值。
✅ 数组索引从 0 开始计起是否让你感觉奇怪?在有的编程语言中,索引会从 1 开始。关于这事有一段有趣的历史,你可以[在维基百科了解它](https://zh.wikipedia.org/zh-cn/%E5%BE%9E%E9%9B%B6%E9%96%8B%E5%A7%8B%E7%9A%84%E7%B7%A8%E8%99%9F)。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
iceCreamFlavors[2]; // "Vanilla"
```
你可以通过索引来改变数组中的值,像这样:
```javascript
iceCreamFlavors[4] = "Butter Pecan"; // 把 "Rocky Road" 改成 "Butter Pecan"
```
你也可以用给定索引来插入新的值,像这样:
```javascript
iceCreamFlavors[5] = "Cookie Dough"; // 加了一项 "Cookie Dough"
```
✅ 向数组中添加新的值有更常用的方法:使用如 array.push() 这样的数组方法
为了获知数组中有多少元素,可以用 `length` 属性。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
iceCreamFlavors.length; // 5
```
✅ 亲手试一试!在你的浏览器控制台里亲手创建和操作一个你自己的数组。
## 循环Loops
数组可以用来做重复性的或者**迭代性的iterative**的工作会省下很多时间和代码量。每一次迭代中的变量、值或者条件可能会不同。JavaScript 中有几种不同类型的循环,它们有一些小差别,但本质上都是做同一件事:遍历数据。
### For 循环
`for` 循环需要三个部分来进行迭代:
- `计数器counter` 一个通常用数字来初始化的变量,用于记录迭代的次数
- `条件式condition` 一个使用了比较运算符的表达式,用于在其值为 `true` 时终止循环
- `迭代式iteration-expression` 在每一次迭代的模为执行,一般用于更新计数器的值
```javascript
// 从 0 数到 9
for (let i = 0; i < 10; i++) {
console.log(i);
}
```
✅ 在浏览器控制台中运行这段代码。试试调整计数器、条件式或迭代式时会发生什么。你能让它反过来运行,倒着计数吗?
### While 循环
`for` 循环不同,`while` 循环只需要一个条件式,用于在其值为 `true` 时终止循环。循环中的条件式往往需要依赖其他的值,比如计数器,计数器也必须得在循环内有所处理。计数器的起始值必须在循环外创建,任何为了达到终止条件的表达式(包括改变计数器的值)都需要在循环内维护。
```javascript
// 从 0 数到 9
let i = 0;
while (i < 10) {
console.log(i);
i++;
}
```
✅ 你在什么时候会选用 for 循环,什么时候会选用 while 循环StackOverflow 上也有数万人有相同的问题,这里有一些[你可能感兴趣的观点](https://stackoverflow.com/questions/39969145/while-loops-vs-for-loops-in-javascript)。
## 循环和数组
循环和数组经常结合使用,因为很多情况下都会利用数组长度来作为条件式,而索引可以作为计数器值。
```javascript
let iceCreamFlavors = ["Chocolate", "Strawberry", "Vanilla", "Pistachio", "Rocky Road"];
for (let i = 0; i < iceCreamFlavors.length; i++) {
console.log(iceCreamFlavors[i]);
} // 所有口味被打印后就会结束循环
```
✅ 在你的浏览器控制台里实验一下遍历一个你自己创建的数组。
---
## 🚀 挑战
除了 for 和 while 循环,还有一些用于遍历数组的办法。比如 [forEach](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)、[for-of](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of) 和 [map](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map)。用这些办法重写一下你的数组遍历代码。
## 课后小测
[Post-lecture quiz](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/14?loc=zh_cn)
## 复习 & 自学
JavaScript 中的数组有许多绑定在上面的方法,对于操作数据来说非常有用。[读一下这些方法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array)并且在你创建的数组上试用一下它们(比如 push、pop、slice 和 splice
## 作业
[循环和数组](assignment.zh-cn.md)

View File

@@ -0,0 +1,13 @@
# 循环和数组
## 说明
编写一段程序,列出 1-20 中所有 3 的倍数,将它们输出到控制台。
> 提示,使用 for 循环,修改迭代表达式
## 评价表
| 指标 | 优秀 | 良好 | 尚可进步 |
| --- | --- | --- | --- |
| | 程序运行正确,并且写了注释 | 没写注释 | 程序未完成或者有 BUG |

View File

@@ -0,0 +1,14 @@
# JavaScript 入门
JavaScript 是 Web 开发的语言。在这四节课中,你将学习它的基础知识。
### 主题
1. [变量和数据类型](../1-data-types/translations/README.zh-cn.md)
2. [函数和方法](../2-functions-methods/translations/README.zh-cn.md)
3. [在 JavaScript 中做出决定](../3-making-decisions/translations/README.zh-cn.md)
4. [数组和循环](../4-arrays-loops/translations/README.zh-cn.md)
### 鸣谢
这些课程由 [Jasmine Greenaway](https://twitter.com/paladique)、[Christopher Harrison](https://twitter.com/geektrainer) 与 [Chris Noring](https://twitter.com/chris_noring) 用 ♥️ 编写