diff --git a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md index 27a7b418a..11b1c0205 100644 --- a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md +++ b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md @@ -17,12 +17,12 @@ let salaries = { alert( sumSalaries(salaries) ); // 650 ``` -Or, optionally, we could also get the sum using `Object.values` and `reduce`: +或,我們也可以使用 `Object.values` 和 `reduce` 取得總和: ```js -// reduce loops over array of salaries, -// adding them up -// and returns the result +// reduce 遍歷整個薪水的陣列 +// 把它們加總起來 +// 然後傳回結果 function sumSalaries(salaries) { return Object.values(salaries).reduce((a, b) => a + b, 0) // 650 } diff --git a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md index 211357d03..0d742c65b 100644 --- a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md +++ b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md @@ -2,15 +2,15 @@ importance: 5 --- -# Sum the properties +# 把屬性加總 -There is a `salaries` object with arbitrary number of salaries. +這裡有個 `salaries` 物件,有任意的薪水數字。 -Write the function `sumSalaries(salaries)` that returns the sum of all salaries using `Object.values` and the `for..of` loop. +撰寫一個函式 `sumSalaries(salaries)`,該函式使用 `Object.values` 和 `for..of` 迴圈來傳回全部薪水的加總。 -If `salaries` is empty, then the result must be `0`. +如果 `salaries` 是空的,那麼結果必須是 `0`。 -For instance: +例如: ```js let salaries = { diff --git a/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md b/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md index d7aebb1fa..bdecc8586 100644 --- a/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md +++ b/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md @@ -4,7 +4,7 @@ importance: 5 # Count properties -Write a function `count(obj)` that returns the number of properties in the object: +寫一個函式 `count(obj)`,該函式會傳回物件有幾個屬性。 ```js let user = { @@ -15,7 +15,7 @@ let user = { alert( count(user) ); // 2 ``` -Try to make the code as short as possible. +嘗試把程式碼盡可能的變短吧。 -P.S. Ignore symbolic properties, count only "regular" ones. +備註:忽略符號的屬性,只計算 "一般的"。 diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md index 4af192515..99baa61f0 100644 --- a/1-js/05-data-types/09-keys-values-entries/article.md +++ b/1-js/05-data-types/09-keys-values-entries/article.md @@ -1,42 +1,42 @@ # Object.keys, values, entries -Let's step away from the individual data structures and talk about the iterations over them. +我們先忽略個別資料結構,然後來討論關於在他們上面迭代這件事情。 -In the previous chapter we saw methods `map.keys()`, `map.values()`, `map.entries()`. +在前面的章節我們看過 `map.keys()`、`map.values()`、`map.entries()` 方法。 -These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too. +這些方法是通用的,這裡通常允許資料結構去使用他們。如果我們曾經建立自有的資料結構,那我們也應該實作他們。 -They are supported for: +他們可以支援: - `Map` - `Set` - `Array` -Plain objects also support similar methods, but the syntax is a bit different. +一般物件也支援類似的方法,但是語法有些不同。 ## Object.keys, values, entries -For plain objects, the following methods are available: +對於一般物件,有以下的方法可以使用: -- [Object.keys(obj)](mdn:js/Object/keys) -- returns an array of keys. -- [Object.values(obj)](mdn:js/Object/values) -- returns an array of values. -- [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of `[key, value]` pairs. +- [Object.keys(obj)](mdn:js/Object/keys) -- 傳回鍵值陣列。 +- [Object.values(obj)](mdn:js/Object/values) -- 傳回值的陣列。 +- [Object.entries(obj)](mdn:js/Object/entries) -- 傳回 `[key, value]` 組成的陣列。 -Please note the distinctions (compared to map for example): +請注意區別(相較於 map 的範例): | | Map | Object | |-------------|------------------|--------------| -| Call syntax | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | -| Returns | iterable | "real" Array | +| 呼叫語法 | `map.keys()` | `Object.keys(obj)`,而不是 `obj.keys()` | +| 傳回 | 可迭代物件 | "實際的" 陣列 | -The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`. +第一個區別是我們必須呼叫 `Object.keys(obj)`,而不是 `obj.keys()`。 -Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `data` that implements its own `data.values()` method. And we still can call `Object.values(data)` on it. +為何如此?主要原因是彈性。記住,在 JavaScript,所有複雜結構都是基於物件。所以我們可能自己有一個像是 `data` 的物件,該物件實作自有的 `data.values()` 方法。而且我們也可以對該物件呼叫 `Object.values(data)`。 -The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons. +第二個區別是 `Object.*` 的方法回傳 "實際的" 陣列物件,而不只是一個可迭代物件。這主要是歷史的原因。 -For instance: +例如: ```js let user = { @@ -49,7 +49,7 @@ let user = { - `Object.values(user) = ["John", 30]` - `Object.entries(user) = [ ["name","John"], ["age",30] ]` -Here's an example of using `Object.values` to loop over property values: +這裡有一個使用 `Object.values` 去遍歷所有屬性值的範例: ```js run let user = { @@ -57,30 +57,30 @@ let user = { age: 30 }; -// loop over values +// 遍歷所有屬性值 for (let value of Object.values(user)) { - alert(value); // John, then 30 + alert(value); // John, 然後是 30 } ``` -```warn header="Object.keys/values/entries ignore symbolic properties" -Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. +```warn header="Object.keys/values/entries 會忽略符號的屬性" +就像 `for..in` 迴圈一樣,這些方法會忽略使用 `Symbol(...)` 作為鍵值的屬性。 -Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. +通常來說這很方便。但是,如果我們也需要符號鍵值的話,則有一個區分的方法 [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols),其傳回只有符號鍵值的陣列。另外,還存在一種方法 [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys),則傳回 **全部的** 鍵值。 ``` -## Transforming objects +## 轉換物件 -Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. +物件缺乏許多存在於陣列的方法,例如 `map`、`filter` 等。 -If we'd like to apply them, then we can use `Object.entries` followed `Object.fromEntries`: +如果我們想應用它們,那麼我們可以使用 `Object.entries` 之後使用 `Object.fromEntries`: -1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. -2. Use array methods on that array, e.g. `map`. -3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. +1. 使用 `Object.entries(obj)` 從 `obj` 取得鍵與值組合的陣列。 +2. 在該陣列上使用陣列方法,例如 `map`。 +3. 在最終結果的陣列使用 `Object.fromEntries(array)` 轉回成一個物件。 -For example, we have an object with prices, and would like to double them: +例如,我們有個一些價格組成的物件,然後想把它們變兩倍: ```js run let prices = { @@ -91,7 +91,7 @@ let prices = { *!* let doublePrices = Object.fromEntries( - // convert to array, map, and then fromEntries gives back the object + // 轉換成陣列,映射,然後以 fromEntries 回給物件 Object.entries(prices).map(([key, value]) => [key, value * 2]) ); */!* @@ -99,4 +99,4 @@ let doublePrices = Object.fromEntries( alert(doublePrices.meat); // 8 ``` -It may look difficult from the first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. +第一次看到時它看起來會很難懂,但是使用一兩次後,會變得很容易理解。我們可以用這個方式做出有力的轉換鏈式。 diff --git a/9-regular-expressions/01-regexp-introduction/article.md b/9-regular-expressions/01-regexp-introduction/article.md index a35d19a7b..6b5aa701c 100644 --- a/9-regular-expressions/01-regexp-introduction/article.md +++ b/9-regular-expressions/01-regexp-introduction/article.md @@ -1,108 +1,101 @@ -# Patterns and flags +# 樣式(Patterns)與 旗標(flags) -Regular expressions are patterns that provide a powerful way to search and replace in text. +正規表達式(Regular expressions)是提供一種有力的方式在文字上去搜尋與取代的模式。 -In JavaScript, they are available via the [RegExp](mdn:js/RegExp) object, as well as being integrated in methods of strings. +在 JavaScript,它們可以藉由 [RegExp](mdn:js/RegExp) 物件使用,也整合進了字串的方法中。 -## Regular Expressions +## 正規表達式 -A regular expression (also "regexp", or just "reg") consists of a *pattern* and optional *flags*. +一個正規表達式(又稱 "regexp",或只寫做 "reg")由一個 **樣式** 與可選用的 **旗標** 組成。 -There are two syntaxes that can be used to create a regular expression object. +這裡有兩種語法可以用來建立一個正規表達式物件。 -The "long" syntax: +較長的語法: ```js regexp = new RegExp("pattern", "flags"); ``` -And the "short" one, using slashes `"/"`: +和較短的,使用斜線 `"/"`: ```js -regexp = /pattern/; // no flags -regexp = /pattern/gmi; // with flags g,m and i (to be covered soon) +regexp = /pattern/; // 沒有旗標 +regexp = /pattern/gmi; // 搭配旗標 g、m 和 i (等一下會講到) ``` -Slashes `pattern:/.../` tell JavaScript that we are creating a regular expression. They play the same role as quotes for strings. +斜線 `pattern:/.../` 會告訴 JavaScript 我們要建立一個正規表達式。它們扮演著跟字串引號相同的角色。 -In both cases `regexp` becomes an instance of the built-in `RegExp` class. +兩種請況下的 `regexp` 都會變成內建 `RegExp` 類別的實體。 -The main difference between these two syntaxes is that pattern using slashes `/.../` does not allow for expressions to be inserted (like string template literals with `${...}`). They are fully static. +兩種語法主要不同之處在於一種使用斜線 `/.../`,不允許插入表達式(像是字串樣板字面值 `${...}`)。他們是完全靜態的。 -Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp`, is more often used when we need to create a regexp "on the fly" from a dynamically generated string. For instance: +斜線用在當我們撰寫程式碼時,所知道的正規表達式 -- 這是最常見的情況。而 `new RegExp`,經常用在我們需要用動態產生的字串建立一個 "即時" 的正規表達式。例如: ```js let tag = prompt("What tag do you want to find?", "h2"); -let regexp = new RegExp(`<${tag}>`); // same as /
$`
|inserts a part of the string before the match|
-|`$'`|inserts a part of the string after the match|
-|`$n`|if `n` is a 1-2 digit number, then it inserts the contents of n-th parentheses, more about it in the chapter $`
|插入匹配結果前面的字串|
+|`$'`|插入匹配結果後面的字串|
+|`$n`|如果 `n` 是一個 1 到 2 位元的數字,那會插入第 n 個括號中的內容,關於更多在此章節