diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md
index 7846f6e21..53a77a46b 100644
--- a/1-js/03-code-quality/04-ninja-code/article.md
+++ b/1-js/03-code-quality/04-ninja-code/article.md
@@ -1,185 +1,180 @@
-# Ninja code
+# 忍者程式碼(Ninja code)
-
-```quote author="Confucius"
-Learning without thought is labor lost; thought without learning is perilous.
+```quote author="孔子"
+學而不思則罔,思而不學則殆。
```
-Programmer ninjas of the past used these tricks to sharpen the mind of code maintainers.
-
-Code review gurus look for them in test tasks.
+過去的程式忍者使用這些技巧來讓程式碼維護者的心思更加敏銳。
-Novice developers sometimes use them even better than programmer ninjas.
+程式碼審查大師得在測試任務中尋找它們。
-Read them carefully and find out who you are -- a ninja, a novice, or maybe a code reviewer?
+初學的開發者有時候將它們用的比程式忍者更好。
+細心閱讀然後找出你的角色是 -- 程式忍者、初學者、或者程式碼審查者?
-```warn header="Irony detected"
-Many try to follow ninja paths. Few succeed.
+```warn header="偵查出諷刺意味"
+很多人試著跟隨忍者的腳步,但很少有人成功。
```
+## 要言不煩(Brevity is the soul of wit)
-## Brevity is the soul of wit
+讓程式碼盡可能簡短,以顯示出你多麼聰明。
-Make the code as short as possible. Show how smart you are.
+讓微妙的語言特性指引你。
-Let subtle language features guide you.
-
-For instance, take a look at this ternary operator `'?'`:
+舉例,看一下這個三元運算子 `'?'`:
```js
-// taken from a well-known javascript library
+// 從知名 JavaScript 函式庫取得的程式碼
i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
```
-Cool, right? If you write like that, a developer who comes across this line and tries to understand what is the value of `i` is going to have a merry time. Then come to you, seeking for an answer.
+酷,對吧?若你也像這樣寫,那些看到這一行程式碼並試圖理解 `i` 值的開發者們,將會有個美好的時光,接著就會來找你尋求答案。
-Tell them that shorter is always better. Initiate them into the paths of ninja.
+告訴他們更短總是更好,引領他們進入忍者之路。
-## One-letter variables
+## 單一字母變數
-```quote author="Laozi (Tao Te Ching)"
-The Dao hides in wordlessness. Only the Dao is well begun and well
-completed.
+```quote author="老子(道德經)"
+道隱無名。夫唯道,善貸且成。
```
-Another way to code faster is to use single-letter variable names everywhere. Like `a`, `b` or `c`.
+另一個寫程式更快的方式是到處使用單一字母的變數名稱,像是 `a`、`b` 或 `c`。
-A short variable disappears in the code like a real ninja in the forest. No one will be able to find it using "search" of the editor. And even if someone does, they won't be able to "decipher" what the name `a` or `b` means.
+短變數會像個真正的忍者處於森林中一樣,消失於程式碼之中,沒有人能夠使用編輯器的 "搜尋" 找到它們。即使有人辦得到,他們也無法 "破譯" `a` 或 `b` 名稱的意義。
-...But there's an exception. A real ninja will never use `i` as the counter in a `"for"` loop. Anywhere, but not here. Look around, there are many more exotic letters. For instance, `x` or `y`.
+...但有個例外,一個真正的忍者永遠不會在 `"for"` 迴圈內使用 `i` 作為計數器。任何地方都行,就是這裡不可以。觀察四周看看,還有其他像是 `x` 或 `y` 這種異樣的字母呢。
-An exotic variable as a loop counter is especially cool if the loop body takes 1-2 pages (make it longer if you can). Then if someone looks deep inside the loop, they won't be able to quickly figure out that the variable named `x` is the loop counter.
+若迴圈本體有 1-2 頁這麼長(若可以就讓它盡量長),那麼以異樣的變數作為迴圈計數器會是特別的酷。然後若有人深入迴圈內部,他們將無法快速知道以 `x` 為名的變數就是迴圈計數器。
-## Use abbreviations
+## 使用縮寫
-If the team rules forbid the use of one-letter and vague names -- shorten them, make abbreviations.
+若團隊規則禁止使用單一字母或模糊的名稱 -- 盡量縮短它們,使用縮寫吧。
-Like this:
+像這樣:
-- `list` -> `lst`.
-- `userAgent` -> `ua`.
-- `browser` -> `brsr`.
-- ...etc
+- `list` -> `lst`。
+- `userAgent` -> `ua`。
+- `browser` -> `brsr`。
+- ...等等
-Only the one with truly good intuition will be able to understand such names. Try to shorten everything. Only a worthy person should be able to uphold the development of your code.
+只有真正擁有良好直覺的人才有辦法理解這些名稱。盡量縮短一切事物,只有天選之人才夠格接手你的程式開發。
-## Soar high. Be abstract.
+## 突破天際的抽象化
-```quote author="Laozi (Tao Te Ching)"
-The great square is cornerless
-The great vessel is last complete,
-The great note is rarified sound,
-The great image has no form.
+```quote author="老子(道德經)"
+大方無隅,
+大器晚成,
+大音希聲,
+大象無形。
```
-While choosing a name try to use the most abstract word. Like `obj`, `data`, `value`, `item`, `elem` and so on.
-
-- **The ideal name for a variable is `data`.** Use it everywhere you can. Indeed, every variable holds *data*, right?
+在選擇一個名稱時,試著使用最為抽象的詞,像是 `obj`、`data`、`value`、`item` 和 `elem` 等等。
- ...But what to do if `data` is already taken? Try `value`, it's also universal. After all, a variable eventually gets a *value*.
+- **變數的理想名稱是 `data`。** 在任何能用地方都用,每個變數都確實都有 *data* 不是嗎?
-- **Name a variable by its type: `str`, `num`...**
+ ...但如果 `data` 已經被用過了怎麼辦?試著使用 `value`,它也很普遍,畢竟一個變數最終總會得到一個 *value*。
- Give them a try. A young initiate may wonder -- are such names really useful for a ninja? Indeed, they are!
+- **使用變數類型命名:`str`、`num`...**
- Sure, the variable name still means something. It says what's inside the variable: a string, a number or something else. But when an outsider tries to understand the code, they'll be surprised to see that there's actually no information at all! And will ultimately fail to alter your well-thought code.
+ 嘗試看看,新手可能會懷疑 -- 這種名稱真的對成為忍者有用嗎?是的,就是會!
- The value type is easy to find out by debugging. But what's the meaning of the variable? Which string/number does it store?
+ 確實,該變數名稱依然含有意義。它說明了變數內部有些什麼:一串字串、一個數值或其它東西。但當外部使用者試著理解程式碼時,他們會驚訝地發現事實上根本不具有任何資訊!且最終將無法改變你精思熟慮過的程式碼。
- There's just no way to figure out without a good meditation!
+ 值的類型很容易就可以經由除錯得知,但此變數的意義呢?它儲存著哪種 字串/數值?
-- **...But what if there are no more such names?** Just add a number: `data1, item2, elem5`...
+ 不經過良好的冥想是無法理解的!
-## Attention test
+- **...但如果這種名稱不夠用怎麼辦?** 加個數字就好了:`data1, item2, elem5`...
-Only a truly attentive programmer should be able to understand your code. But how to check that?
+## 注意力測試
-**One of the ways -- use similar variable names, like `date` and `data`.**
+只有真正細心的程式設計師才夠格理解你的程式碼,要如何確認?
-Mix them where you can.
+**其中一個方法 -- 使用相似的名稱,像是:`date` 和 `data`。**
-A quick read of such code becomes impossible. And when there's a typo... Ummm... We're stuck for long, time to drink tea.
+盡可能的混合在一起。
+快速閱讀這種程式碼是不可能的,而且當還有錯字時... 嗯... 我們卡在這很久了,來喝個茶吧。
-## Smart synonyms
+## 聰明的同義詞
-```quote author="Confucius"
-The hardest thing of all is to find a black cat in a dark room, especially if there is no cat.
+```quote author="孔子"
+最困難的事是在黑暗的房間內尋找一隻黑貓,尤其當那裡根本沒有貓時。
+(譯者註:這則引用應是個烏龍,孔子沒有說過這句話,可上網查詢相關來源)
```
-Using *similar* names for *same* things makes life more interesting and shows your creativity to the public.
+對 *同件* 事情使用 *相似* 的名稱使得生活更為有趣,並向大眾顯示出你的創意。
-For instance, consider function prefixes. If a function shows a message on the screen -- start it with `display…`, like `displayMessage`. And then if another function shows on the screen something else, like a user name, start it with `show…` (like `showName`).
+例如,函式前置。若某個函式在螢幕上顯示一段訊息 -- 使用 `display...` 開頭,像是 `displayMessage`。然後若另一個函式在螢幕上顯示別的東西,像是使用者名稱,就用 `show...` 開頭(像是 `showName`)。
-Insinuate that there's a subtle difference between such functions, while there is none.
+暗示這些函式之間有些微妙的不同,而其實並沒有。
-Make a pact with fellow ninjas of the team: if John starts "showing" functions with `display...` in his code, then Peter could use `render..`, and Ann -- `paint...`. Note how much more interesting and diverse the code became.
+與團隊中的忍者夥伴達成一個協議:若 John 在程式碼中用 `display...` 作為 "顯示" 函式的起始,那 Peter 可以用 `render..`,而 Ann 就用 `paint...`,注意看看程式碼會變得多麼有趣且多樣化啊。
-...And now the hat trick!
+...接著是帽子戲法!
-For two functions with important differences -- use the same prefix!
+對於兩個有著重要差異的函式 -- 使用同樣的前置!
-For instance, the function `printPage(page)` will use a printer. And the function `printText(text)` will put the text on-screen. Let an unfamiliar reader think well over similarly named function `printMessage`: "Where does it put the message? To a printer or on the screen?". To make it really shine, `printMessage(message)` should output it in the new window!
+舉個例,函式 `printPage(page)` 將會用到印表機,而函式 `printText(text)` 將會把文字放到螢幕上。讓某個不熟悉的讀者思考一下這個相似的函式名稱 `printMessage`:"它會把訊息丟到哪去?印表機還是螢幕上?" 為了讓它更為耀眼,`printMessage(message)` 應該要輸出訊息到新的視窗中!
-## Reuse names
+## 重複使用名稱
-```quote author="Laozi (Tao Te Ching)"
-Once the whole is divided, the parts
-need names.
-There are already enough names.
-One must know when to stop.
+```quote author="老子(道德經)"
+始制有名,
+名亦既有,
+夫亦將知止。
+知止所以不殆。
```
-Add a new variable only when absolutely necessary.
+只在絕對需要時才加入新的變數。
-Instead, reuse existing names. Just write new values into them.
+否則,重複使用已存在的名稱。就只要對它們寫入新的值。
-In a function try to use only variables passed as parameters.
+在函式中試著只使用作為參數傳遞的變數。
-That would make it really hard to identify what's exactly in the variable *now*. And also where it comes from. The purpose is to develop the intuition and memory of a person reading the code. A person with weak intuition would have to analyze the code line-by-line and track the changes through every code branch.
+這樣做變數 *現在* 的值到底是什麼會變得很難確定,也會不知道它從哪來的。這麼做的目的是為了開發閱讀程式碼的人的直覺和記性。直覺不佳的人必須一行一行分析程式碼,並追蹤每段程式碼分枝的變化。
-**An advanced variant of the approach is to covertly (!) replace the value with something alike in the middle of a loop or a function.**
+**這種方法的進階變化是偷偷地(!)在像是迴圈或函式之中換掉它的值。**
-For instance:
+舉個例:
```js
function ninjaFunction(elem) {
- // 20 lines of code working with elem
+ // 20 行程式碼用來處理 elem
elem = clone(elem);
- // 20 more lines, now working with the clone of the elem!
+ // 另外的 20 行,用來處理複製後的 elem!
}
```
-A fellow programmer who wants to work with `elem` in the second half of the function will be surprised... Only during the debugging, after examining the code they will find out that they're working with a clone!
+想要在函式第二部分使用 `elem` 的程式夥伴會非常驚訝... 只有在除錯檢查完程式碼後,他們才會發現原來他們是在使用複製體!
-Seen in code regularly. Deadly effective even against an experienced ninja.
+這經常在程式碼中看到,即使是對於經驗豐富的忍者來說也是非常致命。
-## Underscores for fun
+## 底線的樂趣
-Put underscores `_` and `__` before variable names. Like `_name` or `__value`. It would be great if only you knew their meaning. Or, better, add them just for fun, without particular meaning at all. Or different meanings in different places.
+在變數名稱前使用底線 `_` 和 `__`,像是 `_name` 或 `__value`。若只有你知道它們的意義就太讚了,或者更棒的是,加上去只是為了樂趣,根本沒有特別的意義存在,或是在不同的地方就有不一樣的意義。
-You kill two rabbits with one shot. First, the code becomes longer and less readable, and the second, a fellow developer may spend a long time trying to figure out what the underscores mean.
+這樣做一箭雙鵰。首先,程式碼變得更長且更不易讀了,再來,開發夥伴會花很長的時間試圖理解底線的意義。
-A smart ninja puts underscores at one spot of code and evades them at other places. That makes the code even more fragile and increases the probability of future errors.
+一個聰明的忍者會把底線放在某處,然後刻意避免在其他地方使用。這會讓程式碼更為脆弱且增加未來出錯的機會。
-## Show your love
+## 展現你的熱情
-Let everyone see how magnificent your entities are! Names like `superElement`, `megaFrame` and `niceItem` will definitely enlighten a reader.
+讓大家看看你是多麼的氣壯山河!像是 `superElement`、`megaFrame` 和 `niceItem` 這種名稱,一定可以達到啟發讀者的功效。
-Indeed, from one hand, something is written: `super..`, `mega..`, `nice..` But from the other hand -- that brings no details. A reader may decide to look for a hidden meaning and meditate for an hour or two of their paid working time.
+從某方面來看,這樣確實有寫下些什麼:`super..`、`mega..`、`nice..`,但從另一方面來看 -- 毫無細節可言。讀者也許得在上班時間花一兩個小時冥想,來尋找背後隱藏的意義。
+## 重疊外部變數
-## Overlap outer variables
-
-```quote author="Guan Yin Zi"
-When in the light, can't see anything in the darkness.
-When in the darkness, can see everything in the light.
+```quote author="關尹子"
+夫處明者,不見暗中一物,
+而處暗者,能見明中區事。
```
-Use same names for variables inside and outside a function. As simple. No efforts to invent new names.
+將函式的內部與外部變數都使用一樣的名稱。很簡單,也不用花時間創造新名稱。
```js
let *!*user*/!* = authenticateUser();
@@ -189,52 +184,51 @@ function render() {
...
...many lines...
...
- ... // <-- a programmer wants to work with user here and...
+ ... // <-- 某個程式設計師想在這裡使用 user,然後...
...
}
```
-A programmer who jumps inside the `render` will probably fail to notice that there's a local `user` shadowing the outer one.
-
-Then they'll try to work with `user` assuming that it's the external variable, the result of `authenticateUser()`... The trap is sprung! Hello, debugger...
+一個跳進 `render` 內的程式設計師,可能會沒注意到有個區域的 `user` 隱蔽了外部的變數。
+然後他們會試圖將 `user` 視為外部變數 `authenticateUser()` 的結果來使用... 翻開覆蓋的陷阱卡!哈囉,除錯器...
-## Side-effects everywhere!
+## 副作用(Side-effects)無所不在!
-There are functions that look like they don't change anything. Like `isReady()`, `checkPermission()`, `findTags()`... They are assumed to carry out calculations, find and return the data, without changing anything outside of them. In other words, without "side-effects".
+有些函式看起來不改變任何東西,像是 `isReady()`、`checkPermission()`、`findTags()`... 他們被設想為執行計算、找出並回傳資料,而不改變內部的任何東西,換句話說就是沒有 "副作用(side-effects)"。
-**A really beautiful trick is to add a "useful" action to them, besides the main task.**
+**有個真正漂亮的技巧,就是在他們的主要任務之外,再加個 "有用的" 動作。**
-An expression of dazed surprise on the face of your colleague when they see a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.
+當你的同事看到一個名為 `is..`、`check..` 或 `find...` 的函式改變了某些東西時,他的臉上一定會充滿迷惑 -- 絕對能拓展你理性的界線。
-**Another way to surprise is to return a non-standard result.**
+**另一個給人驚喜的方式是回傳非標準的結果。**
-Show your original thinking! Let the call of `checkPermission` return not `true/false`, but a complex object with the results of the check.
+展現你原始的想法!讓 `checkPermission` 呼叫不回傳 `true/false`,而是回傳某個包含檢查結果的複雜物件。
-Those developers who try to write `if (checkPermission(..))`, will wonder why it doesn't work. Tell them: "Read the docs!". And give this article.
+那些試圖寫下 `if (checkPermission(..))` 的開發者,會懷疑為什麼這麼寫不起作用。告訴他們:"看文件!",然後把這篇文章丟給他們。
+## 強大的函式!
-## Powerful functions!
-
-```quote author="Laozi (Tao Te Ching)"
-The great Tao flows everywhere,
-both to the left and to the right.
+```quote author="老子(道德經)"
+大道泛兮,
+其可左右。
```
-Don't limit the function by what's written in its name. Be broader.
+別讓名稱限制了函式,變得更廣泛吧。
+
+舉個例,函式 `validateEmail(email)` 可以(除了檢查 email 是否正確之外)顯示錯誤訊息並要求重新輸入 email。
-For instance, a function `validateEmail(email)` could (besides checking the email for correctness) show an error message and ask to re-enter the email.
+額外的動作不該明顯出現在函式名稱中,真正的忍者程式人員會使它們在程式碼中也不這麼顯眼。
-Additional actions should not be obvious from the function name. A true ninja coder will make them not obvious from the code as well.
+**把多個動作合併成一個以避免你的程式碼被重複使用。**
-**Joining several actions into one protects your code from reuse.**
+想像一下,別的開發者只想要檢查 email 而不要輸出任何訊息時,你的函式 `validateEmail(email)` 做這麼多事就不適合他們啦。所以他們才不會在你冥想的時候來問你問題。
-Imagine, another developer wants only to check the email, and not output any message. Your function `validateEmail(email)` that does both will not suit them. So they won't break your meditation by asking anything about it.
+## 總結
-## Summary
+上述的 "這些建議" 都由實際的程式碼得來... 有時甚至是由有經驗的開發者寫下的,甚至是比你更有經驗的人 ;)
-All "pieces of advice" above are from the real code... Sometimes, written by experienced developers. Maybe even more experienced than you are ;)
+- 遵循部分,你的程式碼會變得充滿驚奇。
+- 遵循多數,你的程式碼會真正成為你的程式碼,沒有人會想改變它。
+- 遵循全部,你的程式碼將成為年輕開發者尋求啟發的寶貴案例。
-- Follow some of them, and your code will become full of surprises.
-- Follow many of them, and your code will become truly yours, no one would want to change it.
-- Follow all, and your code will become a valuable lesson for young developers looking for enlightenment.