From 0fbace8b8c930c5dfb04ec43d3d2ea109bce7993 Mon Sep 17 00:00:00 2001 From: dennis Date: Fri, 3 Jul 2020 19:08:57 +1000 Subject: [PATCH 1/4] Nullish coalescing operator '??' --- .../12-nullish-coalescing-operator/article.md | 87 ++++++++++--------- 1 file changed, 44 insertions(+), 43 deletions(-) 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 f0f6687a3e..3fec183fd0 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 @@ -1,57 +1,58 @@ -# Nullish coalescing operator '??' +# 空合并运算符 '??' [recent browser="new"] -The nullish coalescing operator `??` provides a short syntax for selecting a first "defined" variable from the list. +空合并运算符 `??` 提供了一种简短的语法用来获取列表中第一个已定义的变量。 -The result of `a ?? b` is: -- `a` if it's not `null` or `undefined`, -- `b`, otherwise. +`a ?? b` 的结果是: +- `a` 如果它不是 `null` 或 `undefined`, +- `b`, 其它情况。 -So, `x = a ?? b` is a short equivalent to: +所以, `x = a ?? b` 等同于 ```js x = (a !== null && a !== undefined) ? a : b; ``` -Here's a longer example. +下面是一个长一点的例子。 -Imagine, we have a user, and there are variables `firstName`, `lastName` or `nickName` for their first name, last name and the nick name. All of them may be undefined, if the user decided not to enter any value. +假设我们有一个用户,用变量 `firstName`, `lastName` 和 `nickName` 代表他的名字,姓氏和昵称。如果用户决定不输入,这些变量可能都未定义。 -We'd like to display the user name: one of these three variables, or show "Anonymous" if nothing is set. - -Let's use the `??` operator to select the first defined one: +我们希望显示用户的名字为以上三个变量之一,或者 "Anonymous" 如果没有定义任何一个变量。 +让我们使用 `??` 运算符选择第一个定义的变量: + ```js run let firstName = null; let lastName = null; let nickName = "Supercoder"; -// show the first not-null/undefined value +// 显示第一个 not-null/undefined 变量值 *!* alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder */!* ``` -## Comparison with || +## 与 || 运算符比较 + +`||` 运算符可以与 `??` 运算符以同样的方式使用。实际上,我们可以用 `||` 替换上面示例中的 `??` 并得到相同的结果, 关于`||`运算符的介绍见 [前一章](info:logical-operators#or-finds-the-first-truthy-value). -The OR `||` operator can be used in the same way as `??`. Actually, we can replace `??` with `||` in the code above and get the same result, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value). +两者重要的区别是: +- `||` 返回第一个 *真* 值。 -The important difference is that: -- `||` returns the first *truthy* value. -- `??` returns the first *defined* value. +- `??` 返回第一个 *已定义的* 值。 -This matters a lot when we'd like to treat `null/undefined` differently from `0`. +在我们处理 `null/undefined` 和 `0` 时,这个区别至关重要。 -For example, consider this: +例如,观察下面的例子: ```js height = height ?? 100; ``` -This sets `height` to `100` if it's not defined. +如果 `height` 未定义,则会把 `100` 赋值给 `height` 。 -Let's compare it with `||`: +让我们与 `||` 进行比较: ```js run let height = 0; @@ -60,71 +61,71 @@ alert(height || 100); // 100 alert(height ?? 100); // 0 ``` -Here, `height || 100` treats zero height as unset, same as `null`, `undefined` or any other falsy value. So the result is `100`. +这里,`height || 100` 对 0 的处理等同于未定义,或任何取值为假的赋值。所以结果是 `100`。 -The `height ?? 100` returns `100` only if `height` is exactly `null` or `undefined`. So the `alert` shows the height value `0` "as is". +`height ?? 100` 当且仅当 `height` 确实是 `null` 或 `undefined` 时返回 `100`。 所以 `alert` 按原样显示 height 的值为 `0`。 -Which behavior is better depends on a particular use case. When zero height is a valid value, then `??` is preferrable. +哪种行为更恰当取决于具体的用例。当0是height的一个合理取值时, `??` 运算符更合适。 -## Precedence +## 优先级 -The precedence of the `??` operator is rather low: `7` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). +`??` 运算符的优先级相当低: `7` 请参考 [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)。 -So `??` is evaluated after most other operations, but before `=` and `?`. +所以 `??` 运算符在大多数运算符之后被解释,但在 `=` 和 `?` 之前。 -If we need to choose a value with `??` in a complex expression, then consider adding parentheses: +如果我们要用 `??` 在复合表达式中取值,需要考虑加括号: ```js run let height = null; let width = null; -// important: use parentheses +// 重要:使用括号 let area = (height ?? 100) * (width ?? 50); alert(area); // 5000 ``` -Otherwise, if we omit parentheses, `*` has the higher precedence than `??` and would run first. +另外,如果我们忽略括号,因为 `*` 的优先级高于 `??` ,将优先执行。 -That would work be the same as: +所以运算过程等同于: ```js -// probably not correct +// 或许不正确 let area = height ?? (100 * width) ?? 50; ``` -There's also a related language-level limitation. +这里还有一个语言级别的限制。 -**Due to safety reasons, it's forbidden to use `??` together with `&&` and `||` operators.** +**出于安全因素,禁止将 `??` 与 `&&` 和 `||` 放在一起使用** -The code below triggers a syntax error: +下列代码将导致一个语法错误: ```js run let x = 1 && 2 ?? 3; // Syntax error ``` -The limitation is surely debatable, but it was added to the language specification with the purpose to avoid programming mistakes, as people start to switch to `??` from `||`. +对这条限制存在争议,但它已经被加入语言规范用来避免编程错误,人们开始使用 `??` 替代 `||`。 -Use explicit parentheses to work around it: +可明确使用括号绕开这条限制: ```js run *!* -let x = (1 && 2) ?? 3; // Works +let x = (1 && 2) ?? 3; // 起作用 */!* alert(x); // 2 ``` -## Summary +## 总结 -- The nullish coalescing operator `??` provides a short way to choose a "defined" value from the list. +- 空合并运算符 `??` 提供了简洁的方式获取列表中"已定义的"值。 - It's used to assign default values to variables: + 它被用来为变量赋默认值 ```js // set height=100, if height is null or undefined height = height ?? 100; ``` -- The operator `??` has a very low precedence, a bit higher than `?` and `=`. -- It's forbidden to use it with `||` or `&&` without explicit parentheses. +- `??` 运算符的优先级非常低,只略高于 `?` 和 `=`。 +- 如不明确添加括号,不能与 `||` 或 `&&` 混用。 From 27927c191e8e3c9f654453adc1bdfe38b9f2af07 Mon Sep 17 00:00:00 2001 From: codetaro Date: Fri, 3 Jul 2020 19:08:57 +1000 Subject: [PATCH 2/4] Nullish coalescing operator '??' --- .../12-nullish-coalescing-operator/article.md | 87 ++++++++++--------- 1 file changed, 44 insertions(+), 43 deletions(-) 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 f0f6687a3e..3fec183fd0 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 @@ -1,57 +1,58 @@ -# Nullish coalescing operator '??' +# 空合并运算符 '??' [recent browser="new"] -The nullish coalescing operator `??` provides a short syntax for selecting a first "defined" variable from the list. +空合并运算符 `??` 提供了一种简短的语法用来获取列表中第一个已定义的变量。 -The result of `a ?? b` is: -- `a` if it's not `null` or `undefined`, -- `b`, otherwise. +`a ?? b` 的结果是: +- `a` 如果它不是 `null` 或 `undefined`, +- `b`, 其它情况。 -So, `x = a ?? b` is a short equivalent to: +所以, `x = a ?? b` 等同于 ```js x = (a !== null && a !== undefined) ? a : b; ``` -Here's a longer example. +下面是一个长一点的例子。 -Imagine, we have a user, and there are variables `firstName`, `lastName` or `nickName` for their first name, last name and the nick name. All of them may be undefined, if the user decided not to enter any value. +假设我们有一个用户,用变量 `firstName`, `lastName` 和 `nickName` 代表他的名字,姓氏和昵称。如果用户决定不输入,这些变量可能都未定义。 -We'd like to display the user name: one of these three variables, or show "Anonymous" if nothing is set. - -Let's use the `??` operator to select the first defined one: +我们希望显示用户的名字为以上三个变量之一,或者 "Anonymous" 如果没有定义任何一个变量。 +让我们使用 `??` 运算符选择第一个定义的变量: + ```js run let firstName = null; let lastName = null; let nickName = "Supercoder"; -// show the first not-null/undefined value +// 显示第一个 not-null/undefined 变量值 *!* alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder */!* ``` -## Comparison with || +## 与 || 运算符比较 + +`||` 运算符可以与 `??` 运算符以同样的方式使用。实际上,我们可以用 `||` 替换上面示例中的 `??` 并得到相同的结果, 关于`||`运算符的介绍见 [前一章](info:logical-operators#or-finds-the-first-truthy-value). -The OR `||` operator can be used in the same way as `??`. Actually, we can replace `??` with `||` in the code above and get the same result, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value). +两者重要的区别是: +- `||` 返回第一个 *真* 值。 -The important difference is that: -- `||` returns the first *truthy* value. -- `??` returns the first *defined* value. +- `??` 返回第一个 *已定义的* 值。 -This matters a lot when we'd like to treat `null/undefined` differently from `0`. +在我们处理 `null/undefined` 和 `0` 时,这个区别至关重要。 -For example, consider this: +例如,观察下面的例子: ```js height = height ?? 100; ``` -This sets `height` to `100` if it's not defined. +如果 `height` 未定义,则会把 `100` 赋值给 `height` 。 -Let's compare it with `||`: +让我们与 `||` 进行比较: ```js run let height = 0; @@ -60,71 +61,71 @@ alert(height || 100); // 100 alert(height ?? 100); // 0 ``` -Here, `height || 100` treats zero height as unset, same as `null`, `undefined` or any other falsy value. So the result is `100`. +这里,`height || 100` 对 0 的处理等同于未定义,或任何取值为假的赋值。所以结果是 `100`。 -The `height ?? 100` returns `100` only if `height` is exactly `null` or `undefined`. So the `alert` shows the height value `0` "as is". +`height ?? 100` 当且仅当 `height` 确实是 `null` 或 `undefined` 时返回 `100`。 所以 `alert` 按原样显示 height 的值为 `0`。 -Which behavior is better depends on a particular use case. When zero height is a valid value, then `??` is preferrable. +哪种行为更恰当取决于具体的用例。当0是height的一个合理取值时, `??` 运算符更合适。 -## Precedence +## 优先级 -The precedence of the `??` operator is rather low: `7` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). +`??` 运算符的优先级相当低: `7` 请参考 [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)。 -So `??` is evaluated after most other operations, but before `=` and `?`. +所以 `??` 运算符在大多数运算符之后被解释,但在 `=` 和 `?` 之前。 -If we need to choose a value with `??` in a complex expression, then consider adding parentheses: +如果我们要用 `??` 在复合表达式中取值,需要考虑加括号: ```js run let height = null; let width = null; -// important: use parentheses +// 重要:使用括号 let area = (height ?? 100) * (width ?? 50); alert(area); // 5000 ``` -Otherwise, if we omit parentheses, `*` has the higher precedence than `??` and would run first. +另外,如果我们忽略括号,因为 `*` 的优先级高于 `??` ,将优先执行。 -That would work be the same as: +所以运算过程等同于: ```js -// probably not correct +// 或许不正确 let area = height ?? (100 * width) ?? 50; ``` -There's also a related language-level limitation. +这里还有一个语言级别的限制。 -**Due to safety reasons, it's forbidden to use `??` together with `&&` and `||` operators.** +**出于安全因素,禁止将 `??` 与 `&&` 和 `||` 放在一起使用** -The code below triggers a syntax error: +下列代码将导致一个语法错误: ```js run let x = 1 && 2 ?? 3; // Syntax error ``` -The limitation is surely debatable, but it was added to the language specification with the purpose to avoid programming mistakes, as people start to switch to `??` from `||`. +对这条限制存在争议,但它已经被加入语言规范用来避免编程错误,人们开始使用 `??` 替代 `||`。 -Use explicit parentheses to work around it: +可明确使用括号绕开这条限制: ```js run *!* -let x = (1 && 2) ?? 3; // Works +let x = (1 && 2) ?? 3; // 起作用 */!* alert(x); // 2 ``` -## Summary +## 总结 -- The nullish coalescing operator `??` provides a short way to choose a "defined" value from the list. +- 空合并运算符 `??` 提供了简洁的方式获取列表中"已定义的"值。 - It's used to assign default values to variables: + 它被用来为变量赋默认值 ```js // set height=100, if height is null or undefined height = height ?? 100; ``` -- The operator `??` has a very low precedence, a bit higher than `?` and `=`. -- It's forbidden to use it with `||` or `&&` without explicit parentheses. +- `??` 运算符的优先级非常低,只略高于 `?` 和 `=`。 +- 如不明确添加括号,不能与 `||` 或 `&&` 混用。 From e9898f30833cace10b8fda62d76d9912a1681ae7 Mon Sep 17 00:00:00 2001 From: LeviDing Date: Sat, 18 Jul 2020 22:15:42 +0800 Subject: [PATCH 3/4] Update article.md --- .../12-nullish-coalescing-operator/article.md | 79 +++++++++---------- 1 file changed, 39 insertions(+), 40 deletions(-) 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 3fec183fd0..a9c6b2448b 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 @@ -1,58 +1,57 @@ -# 空合并运算符 '??' +# 空值合并运算符 '??' [recent browser="new"] -空合并运算符 `??` 提供了一种简短的语法用来获取列表中第一个已定义的变量。 +空值合并运算符 `??` 提供了一种简短的语法,用来获取列表中第一个“已定义”的变量(译注:即值不是 `null` 或 `undefined` 的变量)。 -`a ?? b` 的结果是: -- `a` 如果它不是 `null` 或 `undefined`, -- `b`, 其它情况。 +`a ?? b` 的结果是: +- `a`,如果 `a` 不是 `null` 或 `undefined`, +- `b`,其他情况。 -所以, `x = a ?? b` 等同于 +所以,`x = a ?? b` 是下面这个表达式的简写: ```js x = (a !== null && a !== undefined) ? a : b; ``` -下面是一个长一点的例子。 +下面是一个更长一点的例子。 -假设我们有一个用户,用变量 `firstName`, `lastName` 和 `nickName` 代表他的名字,姓氏和昵称。如果用户决定不输入,这些变量可能都未定义。 +假设,我们有一个用户,变量 `firstName`、`lastName` 和 `nickName` 分别对应用户的名字、姓氏和昵称。如果用户决定不输入任何值,那么这些变量都可能是未定义的。 -我们希望显示用户的名字为以上三个变量之一,或者 "Anonymous" 如果没有定义任何一个变量。 +我们想要显示用户的名称:显示这三个变量中的一个,如果都没有设置值,则显示 "Anonymous"。 + +让我们使用 `??` 运算符选择第一个已定义的变量: -让我们使用 `??` 运算符选择第一个定义的变量: - ```js run let firstName = null; let lastName = null; let nickName = "Supercoder"; -// 显示第一个 not-null/undefined 变量值 +// 显示第一个不是 null/undefined 的值 *!* alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder */!* ``` -## 与 || 运算符比较 - -`||` 运算符可以与 `??` 运算符以同样的方式使用。实际上,我们可以用 `||` 替换上面示例中的 `??` 并得到相同的结果, 关于`||`运算符的介绍见 [前一章](info:logical-operators#or-finds-the-first-truthy-value). +## 与 || 比较 -两者重要的区别是: -- `||` 返回第一个 *真* 值。 +或运算符 `||` 可以与 `??` 运算符以同样的方式使用。正如 [上一章](info:logical-operators#or-finds-the-first-truthy-value) 所讲的,我们可以用 `||` 替换上面示例中的 `??`,也可以获得相同的结果。 -- `??` 返回第一个 *已定义的* 值。 +重要的区别是: +- `||` 返回第一个 **真** 值。 +- `??` 返回第一个 **已定义的** 值。 -在我们处理 `null/undefined` 和 `0` 时,这个区别至关重要。 +当我们想将 `null/undefined` 与 `0` 区别对待时,这个区别至关重要。 -例如,观察下面的例子: +例如,考虑下面这种情况: ```js height = height ?? 100; ``` -如果 `height` 未定义,则会把 `100` 赋值给 `height` 。 +如果 `height` 未定义,将其赋值为 `100`。 -让我们与 `||` 进行比较: +让我们将其与 `||` 进行比较: ```js run let height = 0; @@ -61,19 +60,19 @@ alert(height || 100); // 100 alert(height ?? 100); // 0 ``` -这里,`height || 100` 对 0 的处理等同于未定义,或任何取值为假的赋值。所以结果是 `100`。 +在这个例子中,`height || 100` 将值为 `0` 的 `height` 视为未设置的(unset),与 `null`、`undefined` 以及任何其他假(falsy)值同等对待。因此得到的结果是 `100`。 -`height ?? 100` 当且仅当 `height` 确实是 `null` 或 `undefined` 时返回 `100`。 所以 `alert` 按原样显示 height 的值为 `0`。 +`height ?? 100` 仅当 `height` 确实是 `null` 或 `undefined` 时才返回 `100`。因此,`alert` 按原样显示了 `height` 值 `0`。 -哪种行为更恰当取决于具体的用例。当0是height的一个合理取值时, `??` 运算符更合适。 +哪种行为更好取决于特定的使用场景。当高度 `0` 为有效值时,`??` 运算符更适合。 ## 优先级 -`??` 运算符的优先级相当低: `7` 请参考 [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table)。 +`??` 运算符的优先级相当低:在 [MDN table](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table) 中为 `7`。 -所以 `??` 运算符在大多数运算符之后被解释,但在 `=` 和 `?` 之前。 +因此,`??` 在大多数其他运算之后,但在 `=` 和 `?` 之前进行运算。 -如果我们要用 `??` 在复合表达式中取值,需要考虑加括号: +如果我们需要在复杂表达式中使用 `??` 进行取值,需要考虑加括号: ```js run let height = null; @@ -85,28 +84,28 @@ let area = (height ?? 100) * (width ?? 50); alert(area); // 5000 ``` -另外,如果我们忽略括号,因为 `*` 的优先级高于 `??` ,将优先执行。 +否则,如果我们省略了括号,`*` 的优先级比 `??` 高,会优先执行。 -所以运算过程等同于: +运算过程将等同于下面这个表达式: ```js -// 或许不正确 +// 可能不正确的 let area = height ?? (100 * width) ?? 50; ``` -这里还有一个语言级别的限制。 +这里还有一个相关的语言级别的限制。 -**出于安全因素,禁止将 `??` 与 `&&` 和 `||` 放在一起使用** +**出于安全原因,禁止将 `??` 运算符与 `&&` 和 `||` 运算符一起使用。 -下列代码将导致一个语法错误: +下面的代码会触发一个语法错误: ```js run let x = 1 && 2 ?? 3; // Syntax error ``` -对这条限制存在争议,但它已经被加入语言规范用来避免编程错误,人们开始使用 `??` 替代 `||`。 +这个限制无疑是值得商榷的,但是它被添加到语言规范中是为了避免编程错误,因为人们开始使用 `??` 替代 `||`。 -可明确使用括号绕开这条限制: +可以明确地使用括号来解决这个问题: ```js run *!* @@ -118,14 +117,14 @@ alert(x); // 2 ## 总结 -- 空合并运算符 `??` 提供了简洁的方式获取列表中"已定义的"值。 +- 空值合并运算符 `??` 提供了一种简洁的方式获取列表中“已定义”的值。 - 它被用来为变量赋默认值 + 它被用于为变量分配默认值: ```js - // set height=100, if height is null or undefined + // 当 height 的值为 null 或 undefined 时,将 height 的值设置为 100 height = height ?? 100; ``` - `??` 运算符的优先级非常低,只略高于 `?` 和 `=`。 -- 如不明确添加括号,不能与 `||` 或 `&&` 混用。 +- 如果没有明确添加括号,不能将其与 `||` 或 `&&` 一起使用。 From 61f511c60f85abbae2432e7773c2e0e63846bffb Mon Sep 17 00:00:00 2001 From: LeviDing Date: Sat, 18 Jul 2020 22:16:45 +0800 Subject: [PATCH 4/4] Update article.md --- 1-js/02-first-steps/12-nullish-coalescing-operator/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a9c6b2448b..7500079611 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 @@ -49,7 +49,7 @@ alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder height = height ?? 100; ``` -如果 `height` 未定义,将其赋值为 `100`。 +如果 `height` 未定义,则将其赋值为 `100`。 让我们将其与 `||` 进行比较: