±(253-1) 范围内的整数。
- `bigint` 用于任意长度的整数。
- `string` 用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的单字符类型。
@@ -282,7 +282,7 @@ JavaScript 中有八种基本的数据类型(译注:前七种为基本数据
- `null` 用于未知的值 —— 只有一个 `null` 值的独立类型。
- `undefined` 用于未定义的值 —— 只有一个 `undefined` 值的独立类型。
- `symbol` 用于唯一的标识符。
-- 以及一种非原始数据类型:
+- 以及一种非原始数据类型(复杂数据类型):
- `object` 用于更复杂的数据结构。
我们可以通过 `typeof` 运算符查看存储在变量中的数据类型。
diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md
index 4e13f1f7dc..2a5427dd06 100644
--- a/1-js/02-first-steps/08-operators/article.md
+++ b/1-js/02-first-steps/08-operators/article.md
@@ -443,7 +443,7 @@ counter++;
逗号运算符 `,` 是最少见最不常使用的运算符之一。有时候它会被用来写更简短的代码,因此为了能够理解代码,我们需要了解它。
-逗号运算符能让我们处理多个语句,使用 `,` 将它们分开。每个语句都运行了,但是只有最后的语句的结果会被返回。
+逗号运算符能让我们处理多个表达式,使用 `,` 将它们分开。每个表达式都运行了,但是只有最后一个的结果会被返回。
举个例子:
@@ -455,7 +455,7 @@ let a = (1 + 2, 3 + 4);
alert( a ); // 7(3 + 4 的结果)
```
-这里,第一个语句 `1 + 2` 运行了,但是它的结果被丢弃了。随后计算 `3 + 4`,并且该计算结果被返回。
+这里,第一个表达式 `1 + 2` 运行了,但是它的结果被丢弃了。随后计算 `3 + 4`,并且该计算结果被返回。
```smart header="逗号运算符的优先级非常低"
请注意逗号运算符的优先级非常低,比 `=` 还要低,因此上面你的例子中圆括号非常重要。
diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
index 672665b5c9..42bb89af48 100644
--- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
+++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
@@ -106,7 +106,7 @@ alert(height ?? 100); // 0
## 优先级
-`??` 运算符的优先级与 `||` 相同,它们的的优先级都为 `4`,详见:[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)。
+`??` 运算符的优先级与 `||` 相同,它们的优先级都为 `3`,详见:[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)。
这意味着,就像 `||` 一样,空值合并运算符在 `=` 和 `?` 运算前计算,但在大多数其他运算(例如 `+` 和 `*`)之后计算。
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
index 42744fe9a6..6dee8a62ca 100644
--- a/1-js/02-first-steps/13-while-for/article.md
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -14,7 +14,7 @@
如果你阅读本文是为了寻找其他类型的循环,那么:
- 用于遍历对象属性的 `for..in` 循环请见:[for..in](info:object#forin)。
-- 用于遍历数组和可迭代对象的循环分别请见:[for..of](info:array#loops) 和 [iterables](info:iterable)。
+- 用于遍历数组和可迭代对象的循环分别请见:[for..of](info:array#xun-huan) 和 [iterables](info:iterable)。
否则,请继续阅读。
```
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 931a32f107..1c4fd571c3 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -7,7 +7,7 @@ JavaScript 引擎背后的团队关于首先要实现什么有着他们自己想
因此,一个 JavaScript 引擎只能实现标准中的一部分是很常见的情况。
-查看语言特性的当前支持状态的一个很好的页面是 func`string`。函数 `func` 被自动调用,接收字符串和嵌入式表达式,并处理它们。你可以在 [docs](mdn:/JavaScript/Reference/Template_literals#Tagged_template_literals) 中阅读更多关于它们的信息。这叫做 "tagged templates"。此功能可以更轻松地将字符串包装到自定义模版或其他函数中,但这很少使用。
diff --git a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
index 9e7f29b3e7..c00ac5dc78 100644
--- a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
+++ b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
@@ -16,19 +16,3 @@ alert(arr[0].name); // John
alert(arr[1].name); // Mary
alert(arr[2].name); // Pete
```
-
-译注:解决方案的代码还可以更短一些
-
-```js
-function sortByAge(arr) {
- arr.sort((a, b) => a.age - b.age);
-}
-```
-
-因为 `sort()` 方法的语法为 `arr.sort([compareFunction])`,如果没有指明 `compareFunction`,那么元素会被按照转换为的字符串的诸个字符的 Unicode 编码进行排序,如果指明了 `compareFunction`,那么数组会按照调用该函数的返回值排序。即 `a` 和 `b` 是两个将要被比较的元素:
-
-- 如果 `compareFunction(a, b)` 小于 `0`,那么 `a` 会被排列到 `b` 之前;
-- 如果 `compareFunction(a, b)` 等于 `0`,那么 `a` 和 `b` 的相对位置不变。备注:ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
-- 如果 `compareFunction(a, b)` 大于 `0`,那么 `b` 会被排列到 `a` 之前。
-
-因此,升序排列的函数可以简写为:`(a, b) => a.age - b.age`。
diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md
index c51a0cfb9c..13b25a096e 100644
--- a/1-js/05-data-types/05-array-methods/article.md
+++ b/1-js/05-data-types/05-array-methods/article.md
@@ -763,7 +763,7 @@ alert(soldiers[1].age); // 23
- `map(func)` —— 根据对每个元素调用 `func` 的结果创建一个新数组。
- `sort(func)` —— 对数组进行原位(in-place)排序,然后返回它。
- `reverse()` —— 原位(in-place)反转数组,然后返回它。
- - `split/join` —— 将字符串转换为数组并返回。
+ - `split/join` —— 将字符串拆分为数组并返回/将数组项组合成字符串并返回。
- `reduce/reduceRight(func, initial)` —— 通过对每个元素调用 `func` 计算数组上的单个值,并在调用之间传递中间结果。
- 其他:
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index ae88472ba7..2055f5c41c 100644
--- a/1-js/05-data-types/06-iterable/article.md
+++ b/1-js/05-data-types/06-iterable/article.md
@@ -5,7 +5,7 @@
数组是可迭代的。但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的。
-如果从技术上讲,对象不是数组,而是表示某物的集合(列表,集合),`for..of` 是一个能够遍历它的很好的语法,因此,让我们来看看如何使其发挥作用。
+如果从严格意义上讲,对象不是数组,而是表示某物的集合(列表,集合),`for..of` 是一个能够遍历它的很好的语法,因此,让我们来看看如何使其发挥作用。
## Symbol.iterator
diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md
index f27d217219..0dbbdd157a 100644
--- a/1-js/05-data-types/12-json/article.md
+++ b/1-js/05-data-types/12-json/article.md
@@ -188,7 +188,7 @@ replacer
: 要编码的属性数组或映射函数 `function(key, value)`。
space
-: 用于格式化的空格数量
+: 用于格式化的空格数量。
大部分情况,`JSON.stringify` 仅与第一个参数一起使用。但是,如果我们需要微调替换过程,比如过滤掉循环引用,我们可以使用 `JSON.stringify` 的第二个参数。
@@ -246,7 +246,7 @@ alert( JSON.stringify(meetup, *!*['title', 'participants', 'place', 'name', 'num
该函数会为每个 `(key,value)` 对调用并返回"已替换"的值,该值将替换原有的值。如果值被跳过了,则为 `undefined`。
-在我们的例子中,我们可以为 `occupiedBy` 以外的所有内容按原样返回 `value`。为了 `occupiedBy`,下面的代码返回 `undefined`:
+在我们的例子中,我们可以为 `occupiedBy` 以外的所有内容按原样返回 `value`。对于 `occupiedBy`,下面的代码返回 `undefined`:
```js run
let room = {
@@ -453,7 +453,7 @@ let json = `{
还有另一种名为 [JSON5](http://json5.org/) 的格式,它允许未加引号的键,也允许注释等。但这是一个独立的库,不在语言的规范中。
-常规的 JSON 格式严格,并不是因为它的开发者很懒,而是为了实现简单,可靠且快速地实现解析算法。
+标准 JSON 格式之所以如此严格,并不是因为它的制定者们偷懒,而是为了能够简单,可靠且快速地实现解析算法。
## 使用 reviver
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index 2e06590300..f728041114 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -28,7 +28,7 @@ pow(2, 4) = 16
function pow(x, n) {
let result = 1;
- // 再循环中,用 x 乘以 result n 次
+ // 在循环中,用 x 乘以 result n 次
for (let i = 0; i < n; i++) { result *= x; } @@ -338,10 +338,10 @@ let company = { 我们可以看到,当我们的函数对一个部门求和时,有两种可能的情况: -1. 要么是由一 **数组** 的人组成的"简单"的部门 —— 这样我们就可以通过一个简单的循环来计算薪资的总和。 +1. 要么是由一个人员 **数组** 构成的"简单"的部门 —— 这样我们就可以通过一个简单的循环来计算薪资的总和。 2. 或者它是一个有 `N` 个子部门的 **对象** —— 那么我们可以通过 `N` 层递归调用来求每一个子部门的薪资,然后将它们合并起来。 -第一种情况是由一数组的人组成的部门,这种情况很简单,是最基础的递归。 +第一种情况是由人员数组构成的部门,这种情况很简单,是最基础的递归。 第二种情况是我们得到的是对象。那么可将这个复杂的任务拆分成适用于更小部门的子任务。它们可能会被继续拆分,但很快或者不久就会拆分到第一种情况那样。 @@ -396,7 +396,7 @@ alert(sumSalaries(company)); // 7700 我们刚刚在上面的公司结构的示例中看过了它。 一个公司的 **部门** 是: -- 一数组的人。 +- 人员数组。 - 或一个 **部门** 对象。 对于 Web 开发者而言,有更熟知的例子:HTML 和 XML 文档。 @@ -513,7 +513,7 @@ list.next = list.next.next; 链表主要的缺点就是我们无法很容易地通过元素的编号获取元素。但在数组中却很容易:`arr[n]` 是一个直接引用。而在链表中,我们需要从起点元素开始,顺着 `next` 找 `N` 次才能获取到第 N 个元素。 -......但是我们也并不是总需要这样的操作。比如,当我们需要一个队列甚至一个 [双向队列](https://en.wikipedia.org/wiki/Double-ended_queue) —— 有序结构必须可以快速地从两端添加/移除元素,但是不需要访问的元素。 +......但是我们也并不是总需要这样的操作。比如,当我们需要一个队列甚至一个 [双向队列](https://en.wikipedia.org/wiki/Double-ended_queue) —— 有序结构必须可以快速地从两端添加/移除元素,无需访问中间元素。 链表可以得到增强: - 我们可以在 `next` 之外,再添加 `prev` 属性来引用前一个元素,以便轻松地往回移动。 diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md index a6efac76ee..6f8c5c1585 100644 --- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md +++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md @@ -227,7 +227,7 @@ alert( Array.from(str) ); // H,e,l,l,o ## 复制 array/object -还记得我们 [之前讲过的](info:object-copy#ke-long-yu-he-bing-objectassign) `Object.assign()` 吗? +还记得我们 [之前讲过的](info:object-copy#cloning-and-merging-object-assign) `Object.assign()` 吗? 使用 spread 语法也可以做同样的事情(译注:也就是进行浅拷贝)。 diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md index bbf1c8f35f..d58009c332 100644 --- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md +++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md @@ -27,7 +27,7 @@ func(); function func() { *!* // 引擎从函数开始就知道局部变量 x, - // 但是变量 x 一直处于"未初始化"(无法使用)的状态,直到结束 let("死区") + // 但是变量 x 一直处于"未初始化"(无法使用)的状态,直到遇到 let,此时"死区"结束 // 因此答案是 error */!* diff --git a/1-js/06-advanced-functions/07-new-function/article.md b/1-js/06-advanced-functions/07-new-function/article.md index 9a7263d790..85326d1fff 100644 --- a/1-js/06-advanced-functions/07-new-function/article.md +++ b/1-js/06-advanced-functions/07-new-function/article.md @@ -92,7 +92,7 @@ getFunc()(); // *!*"test"*/!*,从 getFunc 的词法环境中获取的 问题在于,在将 JavaScript 发布到生产环境之前,需要使用 **压缩程序(minifier)** 对其进行压缩 —— 一个特殊的程序,通过删除多余的注释和空格等压缩代码 —— 更重要的是,将局部变量命名为较短的变量。 -例如,如果一个函数有 `let userName`,压缩程序会把它替换为 `let a`(如果 a 已被占用了,那就使用其他字符),剩余的局部变量也会被进行类似的替换。一般来说这样的替换是安全的,毕竟这些变量是函数内的局部变量,函数外的任何东西都无法访问它。在函数内部,压缩程序会替换所有使用了使用了这些变量的代码。压缩程序很聪明,它会分析代码的结构,而不是呆板地查找然后替换,因此它不会"破坏"你的程序。 +例如,如果一个函数有 `let userName`,压缩程序会把它替换为 `let a`(如果 a 已被占用了,那就使用其他字符),剩余的局部变量也会被进行类似的替换。一般来说这样的替换是安全的,毕竟这些变量是函数内的局部变量,函数外的任何东西都无法访问它。在函数内部,压缩程序会替换所有使用了这些变量的代码。压缩程序很聪明,它会分析代码的结构,而不是呆板地查找然后替换,因此它不会"破坏"你的程序。 但是在这种情况下,如果使 `new Function` 可以访问自身函数以外的变量,它也很有可能无法找到重命名的 `userName`,这是因为新函数的创建发生在代码压缩以后,变量名已经被替换了。 diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md index 7d747cc452..6ed9ccf703 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md @@ -32,7 +32,7 @@ function throttle(func, ms) { 调用 `throttle(func, ms)` 返回 `wrapper`。 1. 在第一次调用期间,`wrapper` 只运行 `func` 并设置冷却状态(`isThrottled = true`)。 -2. 在这种状态下,所有调用都记忆在 `savedArgs/savedThis` 中。请注意,上下文和参数(arguments)同等重要,应该被记下来。我们同时需要他们以重现调用。 -3. ......然后经过 `ms` 毫秒后,触发 `setTimeout`。冷却状态被移除(`isThrottled = false`),如果我们忽略了调用,则将使用最后记忆的参数和上下文执行 `wrapper`。 +2. 在冷却状态下,所有调用都被保存在 `savedArgs/savedThis` 中。请注意,上下文(this)和参数(arguments)都很重要,应该被保存下来。我们需要它们来重现调用。 +3. 经过 `ms` 毫秒后,`setTimeout`中的函数被触发。冷却状态被移除(`isThrottled = false`),如果存在被忽略的调用,将使用最后一次调用保存的参数和上下文运行 `wrapper`。 -第 3 步运行的不是 `func`,而是 `wrapper`,因为我们不仅需要执行 `func`,还需要再次进入冷却状态并设置 timeout 以重置它。 +第 3 步运行的不是 `func`,而是 `wrapper`,因为我们不仅需要执行 `func`,还需要再次进入冷却状态并设置 `setTimeout` 以重置节流。 diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md index 8739fd2dc4..53bd1f0b7b 100644 --- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md +++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md @@ -413,7 +413,7 @@ hash(1, 2); - [func.call(context, arg1, arg2...)](mdn:js/Function/call) —— 用给定的上下文和参数调用 `func`。 - [func.apply(context, args)](mdn:js/Function/apply) —— 调用 `func` 将 `context` 作为 `this` 和类数组的 `args` 传递给参数列表。 -通用的 **呼叫转移(call forwarding)** 通常是使用 `apply` 完成的: +通用的 **调用传递(call forwarding)** 通常是使用 `apply` 完成的: ```js let wrapper = function() { diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md index 64428b3b95..a0a7f19cb9 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md @@ -8,7 +8,7 @@ importance: 5 `user` 对象被修改了。现在不是两个函数 `loginOk/loginFail`,现在只有一个函数 `user.login(true/false)`。 -在下面的代码中,我们应该向 `askPassword` 传入什么参数,以使得 `user.login(true)` 结果是 `ok`,`user.login(fasle)` 结果是 `fail`? +在下面的代码中,我们应该向 `askPassword` 传入什么参数,以使得 `user.login(true)` 结果是 `ok`,`user.login(false)` 结果是 `fail`? ```js function askPassword(ok, fail) { diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 6cae8ca561..d442ae1af8 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -275,7 +275,7 @@ alert( triple(5) ); // = mul(3, 5) = 15 ## 在没有上下文情况下的 partial -当我们想绑定一些参数(arguments),但是这里没有上下文 `this`,应该怎么办?例如,对于一个对象方法。 +当我们想绑定一些参数(arguments),但是不想绑定上下文 `this`,应该怎么办?例如,对于一个对象方法。 原生的 `bind` 不允许这种情况。我们不可以省略上下文直接跳到参数(arguments)。 @@ -319,7 +319,7 @@ user.sayNow("Hello"); ## 总结 -方法 `func.bind(context, ...args)` 返回函数 `func` 的"绑定的(bound)变体",它绑定了上下文 `this` 和第一个参数(如果给定了)。 +方法 `func.bind(context, ...args)` 返回函数 `func` 的"绑定的(bound)变体",它绑定了上下文 `this` 和 `...args` 参数。 通常我们应用 `bind` 来绑定对象方法的 `this`,这样我们就可以把它们传递到其他地方使用。例如,传递给 `setTimeout`。 diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md index 377b4f5046..7f2e2ed156 100644 --- a/1-js/08-prototypes/04-prototype-methods/article.md +++ b/1-js/08-prototypes/04-prototype-methods/article.md @@ -214,7 +214,7 @@ alert(Object.keys(chineseDictionary)); // hello,bye - [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) —— 返回对象 `obj` 的 `[[Prototype]]`(与 `__proto__` 的 getter 相同)。 - [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) —— 将对象 `obj` 的 `[[Prototype]]` 设置为 `proto`(与 `__proto__` 的 setter 相同)。 -- 不推荐使用内建的的 `__proto__` getter/setter 获取/设置原型,它现在在 ECMA 规范的附录 B 中。 +- 不推荐使用内建的 `__proto__` getter/setter 获取/设置原型,它现在在 ECMA 规范的附录 B 中。 - 我们还介绍了使用 `Object.create(null)` 或 `{__proto__: null}` 创建的无原型的对象。 diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index d49b005c37..c639144d59 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -317,7 +317,7 @@ new User().sayHi(); // Hello, John! 所以,我们就只需在表达式中写 "