Skip to content

Commit bd65547

Browse files
authoredJul 18, 2020
Update some chapters to [Jul 17, 2020] Part-4 (#768)
* update some chapters to [Jun 28, 2020] * update some files
1 parent 9767d68 commit bd65547

File tree

17 files changed

+163
-54
lines changed

17 files changed

+163
-54
lines changed
 

‎1-js/05-data-types/02-number/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ alert( num.toString(2) ); // 11111111
148148

149149
1. 乘除法
150150

151-
例如,要将数字舍入到小数点后两位,我们可以将数字乘以 `100`,调用舍入函数,然后再将其除回。
151+
例如,要将数字舍入到小数点后两位,我们可以将数字乘以 `100`(或更大的 10 的整数次幂),调用舍入函数,然后再将其除回。
152152
```js run
153153
let num = 1.23456;
154154

‎1-js/05-data-types/10-destructuring-assignment/article.md

+19
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,25 @@ for (let [key, value] of user) {
121121
}
122122
```
123123
````
124+
125+
```smart header="Swap variables trick"
126+
A well-known trick for swapping values of two variables:
127+
128+
```js run
129+
let guest = "Jane";
130+
let admin = "Pete";
131+
132+
// Swap values: make guest=Pete, admin=Jane
133+
[guest, admin] = [admin, guest];
134+
135+
alert(`${guest} ${admin}`); // Pete Jane (successfully swapped!)
136+
```
137+
138+
Here we create a temporary array of two variables and immediately destructure it in swapped order.
139+
140+
We can swap more than two variables this way.
141+
142+
124143
### 剩余的 '...'
125144

126145
如果我们不只是要获得第一个值,还要将后续的所有元素都收集起来 — 我们可以使用三个点 `"..."` 来再加一个参数来接收“剩余的”元素:

‎1-js/05-data-types/11-date/6-get-seconds-today/solution.md

+2
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ function getSecondsToday() {
2323
let d = new Date();
2424
return d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
2525
};
26+
27+
alert( getSecondsToday() );
2628
```

‎1-js/06-advanced-functions/02-rest-parameters-spread/article.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,11 @@ alert( Array.from(str) ); // H,e,l,l,o
225225
因此,对于将一些“东西”转换为数组的任务,`Array.from` 往往更通用。
226226
227227
228-
## 获取一个 object/array 的副本
228+
## 获取一个 array/object 的副本
229229
230-
还记得我们 [之前讲过的](https://zh.javascript.info/object#fu-zhi-he-he-bing-objectassign) `Object.assign()` 吗?
230+
还记得我们 [之前讲过的](info:object-copy#fu-zhi-he-he-bing-objectassign) `Object.assign()` 吗?
231231
232-
使用 spread 操作符也可以做同样的事情
232+
使用 spread 语法也可以做同样的事情
233233
234234
```js run
235235
let arr = [1, 2, 3];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function byField(fieldName){
2+
return (a, b) => a[fieldName] > b[fieldName] ? 1 : -1;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function byField(fieldName){
2+
3+
// Your code goes here.
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
describe("byField", function(){
2+
3+
let users = [
4+
{ name: "John", age: 20, surname: "Johnson" },
5+
{ name: "Pete", age: 18, surname: "Peterson" },
6+
{ name: "Ann", age: 19, surname: "Hathaway" },
7+
];
8+
9+
it("sorts users by name", function(){
10+
let nameSortedKey = [
11+
{ name: "Ann", age: 19, surname: "Hathaway" },
12+
{ name: "John", age: 20, surname: "Johnson"},
13+
{ name: "Pete", age: 18, surname: "Peterson" },
14+
];
15+
let nameSortedAnswer = users.sort(byField("name"));
16+
assert.deepEqual(nameSortedKey, nameSortedAnswer);
17+
});
18+
19+
it("sorts users by age", function(){
20+
let ageSortedKey = [
21+
{ name: "Pete", age: 18, surname: "Peterson" },
22+
{ name: "Ann", age: 19, surname: "Hathaway" },
23+
{ name: "John", age: 20, surname: "Johnson"},
24+
];
25+
let ageSortedAnswer = users.sort(byField("age"));
26+
assert.deepEqual(ageSortedKey, ageSortedKey);
27+
});
28+
29+
it("sorts users by surname", function(){
30+
let surnameSortedKey = [
31+
{ name: "Ann", age: 19, surname: "Hathaway" },
32+
{ name: "John", age: 20, surname: "Johnson"},
33+
{ name: "Pete", age: 18, surname: "Peterson" },
34+
];
35+
let surnameSortedAnswer = users.sort(byField("surname"));
36+
assert.deepEqual(surnameSortedAnswer, surnameSortedKey);
37+
});
38+
39+
});
Original file line numberDiff line numberDiff line change
@@ -1,22 +1 @@
11

2-
3-
```js run
4-
let users = [
5-
{ name: "John", age: 20, surname: "Johnson" },
6-
{ name: "Pete", age: 18, surname: "Peterson" },
7-
{ name: "Ann", age: 19, surname: "Hathaway" }
8-
];
9-
10-
*!*
11-
function byField(field) {
12-
return (a, b) => a[field] > b[field] ? 1 : -1;
13-
}
14-
*/!*
15-
16-
users.sort(byField('name'));
17-
users.forEach(user => alert(user.name)); // Ann, John, Pete
18-
19-
users.sort(byField('age'));
20-
users.forEach(user => alert(user.name)); // Pete, Ann, John
21-
```
22-

‎1-js/06-advanced-functions/04-var/article.md

+28-17
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,18 @@
1313
2. `const`
1414
3. `var`
1515

16-
`let``const` 在词法环境中的行为完全一样。
17-
18-
`var` 却是一头完全不同的,源自非常古老的时代的怪兽。在现代脚本中一般不再使用它,但它仍然潜伏在旧脚本中。
19-
20-
如果你不打算接触这样的脚本,你甚至可以跳过本章或推迟阅读本章,但是之后你很可能会踩到它的坑。
21-
22-
乍一看,`var``let` 的行为相似,不就是声明变量嘛:
16+
The `var` declaration is similar to `let`. Most of the time we can replace `let` by `var` or vice-versa and expect things to work:
2317

2418
```js run
25-
function sayHi() {
26-
 var phrase = "Hello"; // 局部变量,使用 "var",而不是 "let"
27-
28-
alert(phrase); // Hello
29-
}
19+
var message = "Hi";
20+
alert(message); // Hi
21+
```
3022

31-
sayHi();
23+
But internally `var` is a very different beast, that originates from very old times. It's generally not used in modern scripts, but still lurks in the old ones.
3224

33-
alert(phrase); // Error, phrase is not defined
34-
```
25+
If you don't plan on meeting such scripts you may even skip this chapter or postpone it.
3526

36-
……但两者存在区别。
27+
On the other hand, it's important to understand differences when migrating old scripts from `var` to `let`, to avoid odd errors.
3728

3829
## "var" 没有块级作用域
3930

@@ -94,7 +85,27 @@ alert(phrase); // Error: phrase is not defined (Check the Developer Console)
9485

9586
可以看到,`var` 穿透了 `if``for` 和其它代码块。这是因为在早期的 JavaScript 中,块没有词法环境。而 `var` 就是这个时期的代表之一。
9687

97-
## "var" 声明在函数开头就会被处理
88+
## "var" 允许重新声明
89+
90+
If we declare the same variable with `let` twice in the same scope, that's an error:
91+
92+
```js run
93+
let user;
94+
let user; // SyntaxError: 'user' has already been declared
95+
```
96+
97+
With `var`, we can redeclare a variable any number of times. If we use `var` with an already-declared variable, it's just ignored:
98+
99+
```js run
100+
var user = "Pete";
101+
102+
var user = "John"; // this "var" does nothing (already declared)
103+
// ...it doesn't trigger an error
104+
105+
alert(user); // John
106+
```
107+
108+
## "var" variables can be declared below their use
98109

99110
当函数开始的时候,就会处理 `var` 声明(脚本启动对应全局变量)。
100111

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function sum(a) {
2+
3+
let currentSum = a;
4+
5+
function f(b) {
6+
currentSum += b;
7+
return f;
8+
}
9+
10+
f.toString = function() {
11+
return currentSum;
12+
};
13+
14+
return f;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function sum(a){
2+
// Your code goes here.
3+
4+
}
5+
6+
/*
7+
sum(1)(2) == 3; // 1 + 2
8+
sum(1)(2)(3) == 6; // 1 + 2 + 3
9+
sum(5)(-1)(2) == 6
10+
sum(6)(-1)(-2)(-3) == 0
11+
sum(0)(1)(2)(3)(4)(5) == 15
12+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
describe("sum", function(){
2+
3+
it("sum(1)(2) == 3", function(){
4+
assert.equal(3, sum(1)(2));
5+
});
6+
7+
it("sum(5)(-1)(2) == 6", function(){
8+
assert.equal(6, sum(5)(-1)(2));
9+
});
10+
11+
it("sum(6)(-1)(-2)(-3) == 0", function(){
12+
assert.equal(0, sum(6)(-1)(-2)(-3));
13+
});
14+
15+
it("sum(0)(1)(2)(3)(4)(5) == 15", function(){
16+
assert.equal(15, sum(0)(1)(2)(3)(4)(5));
17+
});
18+
});
19+

‎1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ describe("throttle(f, 1000)", function() {
77
}
88

99
before(function() {
10-
f1000 = throttle(f, 1000);
1110
this.clock = sinon.useFakeTimers();
11+
f1000 = throttle(f, 1000);
1212
});
1313

1414
it("the first call runs now", function() {

‎1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ importance: 5
44

55
# 节流装饰者
66

7-
创建一个“节流”装饰者 `throttle(f, ms)` —— 返回一个包装器,最多每隔 `1ms` 将调用传递给 `f` 一次。那些属于“冷却”期的调用将被忽略
7+
创建一个“节流”装饰者 `throttle(f, ms)` —— 返回一个包装器。
88

9-
**`debounce` 的区别 —— 如果被忽略的调用是冷却期间的最后一次,那么它会在延时结束时执行。**
9+
When it's called multiple times, it passes the call to `f` at maximum once per `ms` milliseconds.
10+
11+
The difference with debounce is that it's completely different decorator:
12+
- `debounce` runs the function once after the "cooldown" period. Good for processing the final result.
13+
- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often.
1014

1115
让我们看看现实生活中的应用程序,以便更好地理解这个需求,并了解它的来源。
1216

1317
**例如,我们想要跟踪鼠标移动。**
1418

1519
在浏览器中,我们可以设置一个函数,使其在每次鼠标移动时运行,并获取鼠标移动时的指针位置。在使用鼠标的过程中,此函数通常会执行地非常频繁,大概每秒 100 次(每 10 毫秒)。
1620

17-
**当鼠标指针移动时,我们想要更新网页上的某些信息**
21+
**我们想要在鼠标指针移动时,更新网页上的某些信息**
1822

1923
……但是更新函数 `update()` 太重了,无法在每个微小移动上都执行。高于每 100ms 更新一次的更新频次也没有意义。
2024

‎1-js/06-advanced-functions/09-call-apply-decorators/article.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ alert( worker.slow(2) ); // 工作正常,没有调用原始函数(使用的
209209
2. 因此,当 `worker.slow(2)` 执行时,包装器将 `2` 作为参数,并且 `this=worker`(它是点符号 `.` 之前的对象)。
210210
3. 在包装器内部,假设结果尚未缓存,`func.call(this, x)` 将当前的 `this``=worker`)和当前的参数(`=2`)传递给原始方法。
211211

212-
## 使用 "func.apply" 来传递多参数
212+
## 传递多个参数
213213

214214
现在让我们把 `cachingDecorator` 写得更加通用。到现在为止,它只能用于单参数函数。
215215

@@ -236,7 +236,7 @@ worker.slow = cachingDecorator(worker.slow);
236236

237237
对于许多实际应用,第三种方式就足够了,所以我们就用这个吧。
238238

239-
当然,我们需要将 `func.call(this, x)` 替换成 `func.call(this, ...arguments)`,以将所有参数传递给包装的函数调用,而不仅仅是只传递第一个参数。
239+
Also we need to pass not just `x`, but all arguments in `func.call`. Let's recall that in a `function()` we can get a pseudo-array of its arguments as `arguments`, so `func.call(this, x)` should be replaced with `func.call(this, ...arguments)`.
240240

241241
这是一个更强大的 `cachingDecorator`
242242

@@ -284,6 +284,8 @@ alert( "Again " + worker.slow(3, 5) ); // same (cached)
284284
-`(*)` 行中它调用 `hash` 来从 `arguments` 创建一个单独的键。这里我们使用一个简单的“连接”函数,将参数 `(3, 5)` 转换为键 `"3,5"`。更复杂的情况可能需要其他哈希函数。
285285
- 然后 `(**)` 行使用 `func.call(this, ...arguments)` 将包装器获得的上下文和所有参数(不仅仅是第一个参数)传递给原始函数。
286286

287+
## func.apply
288+
287289
我们可以使用 `func.apply(this, arguments)` 代替 `func.call(this, ...arguments)`
288290

289291
内建方法 [func.apply](mdn:js/Function/apply) 的语法是:
@@ -308,9 +310,9 @@ func.apply(context, args); // 与使用 call 相同
308310
- Spread 语法 `...` 允许将 **可迭代对象** `args` 作为列表传递给 `call`
309311
- `apply` 仅接受 **类数组对象** `args`
310312

311-
因此,这些调用可以相互补充。当我们期望可迭代对象时,使用 `call`,当我们期望类数组对象时,使用 `apply`
313+
因此,当我们期望可迭代对象时,使用 `call`,当我们期望类数组对象时,使用 `apply`
312314

313-
对于即可迭代又是类数组的对象,例如一个真正的数组,从技术上讲我们使用 `call``apply` 都行,但是 `apply` 可能会更快,因为大多数 JavaScript 引擎在内部对其进行了优化。
315+
对于即可迭代又是类数组的对象,例如一个真正的数组,我们使用 `call``apply` 均可,但是 `apply` 可能会更快,因为大多数 JavaScript 引擎在内部对其进行了优化。
314316

315317
将所有参数连同上下文一起传递给另一个函数被称为“呼叫转移(call forwarding)”。
316318

‎1-js/07-object-properties/02-property-accessors/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
# 属性的 getter 和 setter
33

4-
有两种类型的属性
4+
有两种类型的对象属性
55

66
第一种是 **数据属性**。我们已经知道如何使用它们了。到目前为止,我们使用过的所有属性都是数据属性。
77

‎1-js/08-prototypes/04-prototype-methods/article.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ alert(rabbit.jumps); // true
5757
我们可以使用 `Object.create` 来实现比复制 `for..in` 循环中的属性更强大的对象克隆方式:
5858

5959
```js
60-
// 完全相同的对象 obj 的浅拷贝
6160
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
6261
```
6362

@@ -116,7 +115,7 @@ alert(obj[key]); // [object Object],并不是 "some value"!
116115

117116
我们怎么避免这样的问题呢?
118117

119-
首先,我们可以改用 `Map`,那么一切都迎刃而解
118+
首先,我们可以改用 `Map` 来代替普通对象进行存储,这样一切都迎刃而解
120119

121120
但是 `Object` 在这里同样可以运行得很好,因为 JavaScript 语言的制造者很早就注意到了这个问题。
122121

@@ -128,7 +127,7 @@ alert(obj[key]); // [object Object],并不是 "some value"!
128127

129128
就像在本部分教程的开头所说的那样:`__proto__` 是一种访问 `[[Prototype]]` 的方式,而不是 `[[prototype]]` 本身。
130129

131-
现在,我们想要将一个对象用作关联数组,我们可以使用一些小技巧:
130+
现在,我们想要将一个对象用作关联数组,并且摆脱此类问题,我们可以使用一些小技巧:
132131

133132
```js run
134133
*!*

0 commit comments

Comments
 (0)
Please sign in to comment.