Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 1-js/01-getting-started/1-intro/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ JavaScript 的能力很大程度上依赖于它执行的环境。例如:[Node.

- 网页中的 JavaScript 不能读、写、复制及执行用户磁盘上的文件或程序。它没有直接访问操作系统的功能。

现代浏览器允许 JavaScript 做一些文件相关的操作,但是这个操作是受到限制的。仅当用户使用某个特定的动作,JavaScript 才能操作这个文件。例如,把文件“拖”到浏览器中,或者通过 `<input>` 标签选择文件。
现代浏览器允许 JavaScript 做一些文件相关的操作,但是这个操作是受到限制的。仅当用户做出特定的行为,JavaScript 才能操作这个文件。例如,把文件“拖”到浏览器中,或者通过 `<input>` 标签选择文件。

JavaScript 有很多方式和照相机/麦克风或者其他设备进行交互,但是这些都需要提前获得用户的授权许可。所以,启用了 JavaScript 的网页应该不会偷偷地启动网络摄像头观察你,并把你的信息发送到[美国国家安全局](https://en.wikipedia.org/wiki/National_Security_Agency)。
- 不同的浏览器标签页之间基本彼此不相关。有时候,也会有一些关系。例如,一个标签页通过 JavaScript 打开另外一个新的标签页。但即使在这种情况下,如果两个标签页打开的不是同一个网站(域名、协议或者端口任一不相同的网站),他们都不能够相互通信。
Expand Down
2 changes: 1 addition & 1 deletion 1-js/02-first-steps/02-structure/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 语句

语句是执行操作的语法结构和命令
语句是执行行为(action)的语法结构和命令

我们已经见过了 `alert('Hello, world!')` 这样可以用来显示消息的语句。

Expand Down
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/07-operators/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ alert( 2 * counter++ ); // 2,因为 counter++ 返回的是“旧值”

当阅读代码时,快速的视觉“纵向”扫描会很容易漏掉 `counter++`,这样的自增操作并不明显。

我们建议“一行一个操作”模式
我们建议用“一行一个行为”的模式

```js run
let counter = 1;
Expand Down Expand Up @@ -430,7 +430,7 @@ alert( a ); // 7(3 + 4 的结果)

为什么我们需要这样一个运算符,它只返回最后一个值呢?

有时候,人们会使用它把几个操作放在一行上来进行复杂的运算
有时候,人们会使用它把几个行为放在一行上来进行复杂的运算

举个例子:

Expand Down
10 changes: 5 additions & 5 deletions 1-js/02-first-steps/14-function-basics/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,9 @@ return (

## 函数命名 [#function-naming]

函数是行为。所以它们的名字通常是动词。它应该简短且尽可能准确地描述函数的作用。这样读代码的人就能清楚地知道这个函数的功能。
函数就是行为(action)。所以它们的名字通常是动词。它应该简短且尽可能准确地描述函数的作用。这样读代码的人就能清楚地知道这个函数的功能。

一种普遍的做法是用动词前缀来开始一个函数,这个前缀模糊地描述了这个动作。团队内部必须就前缀的含义达成一致。
一种普遍的做法是用动词前缀来开始一个函数,这个前缀模糊地描述了这个行为。团队内部必须就前缀的含义达成一致。

例如,以 `"show"` 开头的函数通常会显示某些内容。

Expand All @@ -380,10 +380,10 @@ checkPermission(..) // 检查权限并返回 true/false

有了前缀,只需瞥一眼函数名,就可以了解它的功能是什么,返回什么样的值。

```smart header="一个函数 —— 做一件事"
```smart header="一个函数 —— 一个行为"
一个函数应该只包含函数名所指定的功能,而不是做更多与函数名无关的功能。

两个独立的操作通常需要两个函数,即使它们通常被一起调用(在这种情况下,我们可以创建第三个函数来调用这两个函数)。
两个独立的行为通常需要两个函数,即使它们通常被一起调用(在这种情况下,我们可以创建第三个函数来调用这两个函数)。

有几个违反这一规则的例子:

Expand Down Expand Up @@ -445,7 +445,7 @@ function isPrime(n) {
}
```

第二个变体更容易理解,不是吗?我们通过函数名(`isPrime`)就可以看出函数的功能,而不需要通过代码。人们通常把这样的代码称为 **自描述**。
第二个变体更容易理解,不是吗?我们通过函数名(`isPrime`)就可以看出函数的行为,而不需要通过代码。人们通常把这样的代码称为 **自描述**。

因此,即使我们不打算重用它们,也可以创建函数。函数可以让代码结构更清晰,可读性更强。

Expand Down
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/15-function-expressions/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ ask(

这样的代码在我们的脚本中非常常见,这正符合 JavaScript 语言的思想。

```smart header="一个函数是表示一个“动作(action)”的值"
```smart header="一个函数是表示一个“行为”的值"
字符串或数字等常规值代表 **数据**。

函数可以被视为一个 **动作**。
函数可以被视为一个 **行为(action)**。

我们可以在变量之间传递它们,并在需要时运行。
```
Expand Down
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/16-arrow-functions-basics/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ welcome();

一开始,箭头函数可能看起来并不熟悉,也不容易读懂,但一旦我们看习惯了之后,这种情况很快就会改变。

箭头函数对于简单的单行动作来说非常方便,尤其是当我们懒得打太多字的时候。
箭头函数对于简单的单行行为(action)来说非常方便,尤其是当我们懒得打太多字的时候。

## 多行的箭头函数

Expand Down Expand Up @@ -100,7 +100,7 @@ alert( sum(1, 2) ); // 3

为了更深入地学习它们,我们首先需要了解一些 JavaScript 其他方面的知识,因此我们将在后面的 <info:arrow-functions> 一章中再继续研究箭头函数。

现在,我们已经可以用箭头函数进行单行操作和回调了
现在,我们已经可以用箭头函数进行单行行为和回调了
```

## 总结
Expand Down
4 changes: 2 additions & 2 deletions 1-js/03-code-quality/01-debugging-chrome/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ function hello(name) {
<span class="devtools" style="background-position:-4px -194px"></span> —— “步入(Step into)”,快捷键 `key:F11`。
: 和“下一步(Step)”类似,但在异步函数调用情况下表现不同。如果你刚刚才开始学 JavaScript,那么你可以先忽略此差异,因为我们还没有用到异步调用。

至于以后,请记住“下一步(Step)”命令会忽略异步方法,例如 `setTimeout`(约定的函数调用),它会过一段时间后再执行。而“步入(Step into)”会进入到代码中并等待(如果需要)。浏览 [DevTools 手册](https://developers.google.com/web/updates/2018/01/devtools#async) 获取更多细节
至于之后,只需要记住“下一步(Step)”命令会忽略异步行为,例如 `setTimeout`(计划的函数调用),它会过一段时间再执行。而“步入(Step into)”会进入到代码中并等待(如果需要)。详见 [DevTools 手册](https://developers.google.com/web/updates/2018/01/devtools#async)。

<span class="devtools" style="background-position:-104px -76px"></span> —— “步出(Step out)”:继续执行到当前函数的末尾,快捷键 `key:Shift+F11`。
<span class="devtools" style="background-position:-32px -194px"></span> —— “步出(Step out)”:继续执行到当前函数的末尾,快捷键 `key:Shift+F11`。
: 继续执行代码并停止在当前函数的最后一行。当我们使用 <span class="devtools" style="background-position:-200px -190px"></span> 偶然地进入到一个嵌套调用,但是我们又对这个函数不感兴趣时,我们想要尽可能的继续执行到最后的时候是非常方便的。

<span class="devtools" style="background-position:-61px -74px"></span> —— 启用/禁用所有的断点。
Expand Down
6 changes: 3 additions & 3 deletions 1-js/03-code-quality/04-ninja-code/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function render() {

有些函数看起来它们不会改变任何东西。例如 `isReady()`,`checkPermission()`,`findTags()`……它们被假定用于执行计算、查找和返回数据,而不会更改任何他们自身之外的数据。这被称为“无副作用”。

**一个非常惊喜的技巧就是,除了主要任务之外,给它们添加一个“有用的”动作。**
**一个非常惊喜的技巧就是,除了主要任务之外,给它们添加一个“有用的”行为。**

当你的同事看到被命名为 `is..`、`check..` 或 `find...` 的函数改变了某些东西的时候,他脸上肯定是一脸懵逼的表情 — 这会扩大你的理性界限。

Expand All @@ -225,9 +225,9 @@ function render() {

例如,函数 `validateEmail(email)` 可以(除了检查邮件的正确性之外)显示一个错误消息并要求重新输入邮件。

额外的动作在函数名称中不应该很明显。一个真正的忍者会使它们在代码中也不明显。
额外的行为在函数名称中不应该很明显。一个真正的忍者会使它们在代码中也不明显。

**将多个动作合并到一起,可以保护你的代码不被重用。**
**将多个行为合并到一起,可以保护你的代码不被重用。**

想象一下,另一个开发者只想检查邮箱而不想输出任何信息。你的函数 `validateEmail(email)` 对他而言就不合适啦。所以他不会找你问关于这些函数的任何事而打断你的思考。

Expand Down
2 changes: 1 addition & 1 deletion 1-js/04-object-basics/04-object-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let user = {

并且,在现实世界中,用户可以进行 **操作**:从购物车中挑选某物、登录和注销等。

在 JavaScript 中,操作通过属性中的函数来表示
在 JavaScript 中,行为(action)由属性中的函数来表示

## 方法示例

Expand Down
2 changes: 1 addition & 1 deletion 1-js/05-data-types/04-array/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ fruits.shift(); // 从首端取出一个元素

那 `push/pop` 是什么样的呢?它们不需要移动任何东西。如果从末端移除一个元素,`pop` 方法只需要清理索引值并缩短 `length` 就可以了。

`pop` 操作的动作:
`pop` 操作的行为:

```js
fruits.pop(); // 从末端取走一个元素
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ name = "Pete";
sayHi(); // 会显示什么:"John" 还是 "Pete"?
```

这种情况在浏览器和服务器端开发中都很常见。一个函数可能被安排在被创建之后一段时间后才执行,例如在用户操作或网络请求之后
这种情况在浏览器和服务器端开发中都很常见。一个函数可能被安排在被创建之后一段时间后才执行,例如在用户行为或网络请求之后

因此,问题是:它会接收最新的修改吗?
2 changes: 1 addition & 1 deletion 1-js/06-advanced-functions/06-function-object/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ JavaScript 中的每个值都有一种类型,那么函数是什么类型呢?

在 JavaScript 中,函数就是对象。

一个容易理解的方式是把函数想象成可被调用的“动作对象(action object)”。我们不仅可以调用它们,还能把它们当作对象来处理:增/删属性,按引用传递等。
一个容易理解的方式是把函数想象成可被调用的“行为对象(action object)”。我们不仅可以调用它们,还能把它们当作对象来处理:增/删属性,按引用传递等。


## 属性 "name"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ user.name = "Pete"; // Error: Cannot assign to read only property 'name'
现在没有人可以改变我们 `user` 的 `name`,除非它们应用自己的 `defineProperty` 来覆盖我们的 `user` 的 `name`。

```smart header="只在严格模式下会出现 Errors"
在非严格模式下,在对不可写的属性等进行写入操作时,不会出现错误。但是操作仍然不会成功。在非严格模式下,违反标志的操作只会被默默的忽略掉
在非严格模式下,在对不可写的属性等进行写入操作时,不会出现错误。但是操作仍然不会成功。在非严格模式下,违反标志的行为(flag-violating action)只会被默默地忽略掉
```

这是相同的示例,但针对的是属性不存在的情况:
Expand Down
18 changes: 9 additions & 9 deletions 1-js/11-async/01-callbacks/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
但是,我们会尽全力使讲解变得更加清晰。在这儿不会有浏览器方面的真正复杂的东西。
```

JavaScipt 主机(host)环境提供了许多函数,这些函数允许我们安排 **异步** 动作(action)。换句话说,我们现在开始执行的动作,但它们会在稍后完成。
JavaScipt 主机(host)环境提供了许多函数,这些函数允许我们安排 **异步** 行为(action)。换句话说,我们现在开始执行的行为,但它们会在稍后完成。

例如,`setTimeout` 函数就是一个这样的函数。

这儿有一些实际中的异步动作的示例,例如加载脚本和模块(我们将在后面的章节中介绍)。
这儿有一些实际中的异步行为的示例,例如加载脚本和模块(我们将在后面的章节中介绍)。

让我们看一下函数 `loadScript(src)`,该函数使用给定的 `src` 加载脚本:

Expand Down Expand Up @@ -87,7 +87,7 @@ loadScript('/my/script.js', function() {
});
```

这是我们的想法:第二个参数是一个函数(通常是匿名函数),该函数会在动作(action)完成时运行。
这是我们的想法:第二个参数是一个函数(通常是匿名函数),该函数会在行为(action)完成时运行。

这是一个带有真实脚本的可运行的示例:

Expand Down Expand Up @@ -151,7 +151,7 @@ loadScript('/my/script.js', function(script) {
});
```

因此,每一个新动作(action)都在回调内部。这对于几个动作来说还好,但对于许多动作来说就不好了,所以我们很快就会看到其他变体。
因此,每一个新行为(action)都在回调内部。这对于几个行为来说还好,但对于许多行为来说就不好了,所以我们很快就会看到其他变体。

## 处理 Error

Expand Down Expand Up @@ -198,7 +198,7 @@ loadScript('/my/script.js', function(error, script) {

乍一看,这是一种可行的异步编程方式。的确如此,对于一个或两个嵌套的调用看起来还不错。

但对于一个接一个的多个异步动作,代码将会变成这样:
但对于一个接一个的多个异步行为,代码将会变成这样:

```js
loadScript('1.js', function(error, script) {
Expand Down Expand Up @@ -263,11 +263,11 @@ loadScript('1.js', function(error, script) {

![](callback-hell.svg)

嵌套调用的“金字塔”随着每个异步动作会向右增长。很快它就失控了。
嵌套调用的“金字塔”随着每个异步行为会向右增长。很快它就失控了。

所以这种编码方式不是很好。

我们可以通过使每个动作都成为一个独立的函数来尝试减轻这种问题,如下所示:
我们可以通过使每个行为都成为一个独立的函数来尝试减轻这种问题,如下所示:

```js
loadScript('1.js', step1);
Expand Down Expand Up @@ -299,11 +299,11 @@ function step3(error, script) {
};
```

看到了吗?它的作用相同,但是没有深层的嵌套了,因为我们将每个动作都编写成了一个独立的顶层函数
看到了吗?它的作用相同,但是没有深层的嵌套了,因为我们将每个行为都编写成了一个独立的顶层函数

它可以工作,但是代码看起来就像是一个被撕裂的表格。你可能已经注意到了,它的可读性很差,在阅读时你需要在各个代码块之间跳转。这很不方便,特别是如果读者对代码不熟悉,他们甚至不知道应该跳转到什么地方。

此外,名为 `step*` 的函数都是一次性使用的,创建它们就是为了避免“厄运金字塔”。没有人会在动作链之外重用它们。因此,这里的命名空间有点混乱。
此外,名为 `step*` 的函数都是一次性使用的,创建它们就是为了避免“厄运金字塔”。没有人会在行为链之外重用它们。因此,这里的命名空间有点混乱。

我们希望还有更好的方法。

Expand Down
6 changes: 3 additions & 3 deletions 1-js/11-async/03-promise-chaining/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ new Promise(function(resolve, reject) {

所以输出与前面的示例相同:1 -> 2 -> 4,但是现在在每次 `alert` 调用之间会有 1 秒钟的延迟。

返回 promise 使我们能够构建异步动作链
返回 promise 使我们能够构建异步行为链

## 示例:loadScript

Expand Down Expand Up @@ -164,7 +164,7 @@ loadScript("/article/promise-chaining/one.js")

在这儿,每个 `loadScript` 调用都返回一个 promise,并且在它 resolve 时下一个 `.then` 开始运行。然后,它启动下一个脚本的加载。所以,脚本是一个接一个地加载的。

我们可以向链中添加更多的异步动作(action)。请注意,代码仍然是“扁平”的 — 它向下增长,而不是向右。这里没有“厄运金字塔”的迹象。
我们可以向链中添加更多的异步行为(action)。请注意,代码仍然是“扁平”的 — 它向下增长,而不是向右。这里没有“厄运金字塔”的迹象。

从技术上讲,我们可以向每个 `loadScript` 直接添加 `.then`,就像这样:

Expand Down Expand Up @@ -321,7 +321,7 @@ fetch('/article/promise-chaining/user.json')

也就是说,第 `(*)` 行的 `.then` 处理程序(handler)现在返回一个 `new Promise`,只有在 `setTimeout` `(**)` 中的 `resolve(githubUser)` 被调用后才会变为 settled。链中的下一个 `.then` 将一直等待这一时刻的到来。

作为一个好的做法,异步行为(action)应该始终返回一个 promise。这样就可以使得之后我们计划后续的行为(action)成为可能。即使我们现在不打算对链进行扩展,但我们之后可能会需要。
作为一个好的做法,异步行为应该始终返回一个 promise。这样就可以使得之后我们计划后续的行为成为可能。即使我们现在不打算对链进行扩展,但我们之后可能会需要。

最后,我们可以将代码拆分为可重用的函数:

Expand Down
2 changes: 1 addition & 1 deletion 1-js/11-async/07-microtask-queue/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ window.addEventListener('unhandledrejection', event => alert(event.reason));

## 总结

Promise 处理始终是异步的,因为所有 promise 操作都会通过内部的 "promise jobs" 队列,也被称为“微任务队列”(ES8 术语)。
Promise 处理始终是异步的,因为所有 promise 行为都会通过内部的 "promise jobs" 队列,也被称为“微任务队列”(ES8 术语)。

因此,`.then/catch/finally` 处理程序(handler)总是在当前代码完成后才会被调用。**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ for(let value of range) {

这有一个自定义的对象 `range`,它是可迭代的,并且它的 generator `*[Symbol.iterator]` 实现了列出值的逻辑。

如果们想要给 generator 加上异步操作,那么我们应该将 `Symbol.iterator` 替换成异步的 `Symbol.asyncIterator`:
如果们想要给 generator 加上异步行为,那么我们应该将 `Symbol.iterator` 替换成异步的 `Symbol.asyncIterator`:

```js run
let range = {
Expand Down
2 changes: 1 addition & 1 deletion 2-ui/1-document/02-dom-nodes/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,6 @@ HTML/XML 文档在浏览器内均被表示为 DOM 树。

我们可以使用开发者工具来检查(inspect)DOM 并手动修改它。

在这里,我们介绍了基础知识,入门最常用和最重要的操作。在 <https://developers.google.cn/web/tools/chrome-devtools> 上有关于 Chrome 开发者工具的详细文档说明。学习这些工具的最佳方式就是到处点一点看一看,阅读菜单:大多数选项都很明显。而后,当你大致了解它们后,请阅读文档并学习其余内容。
在这里,我们介绍了基础知识,入门最常用和最重要的行为。在 <https://developers.google.cn/web/tools/chrome-devtools> 上有关于 Chrome 开发者工具的详细文档说明。学习这些工具的最佳方式就是到处点一点看一看,阅读菜单:大多数选项都很明显。而后,当你大致了解它们后,请阅读文档并学习其余内容。

DOM 节点具有允许我们在它们之间移动,修改它们,在页面中移动等的属性和方法。在下一章中,我们将介绍它们。
Loading