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 886f2cf41..8291d1d6d 100644 --- a/1-js/03-code-quality/04-ninja-code/article.md +++ b/1-js/03-code-quality/04-ninja-code/article.md @@ -1,179 +1,180 @@ # โค้ดนินจา -```quote author="ขงจื๊อ (คำภีร์)" -ไร้คิดร่ำเรียน เสมือนไร้ผล หลงคิดไร้เรียน อันตรายหนา +```quote author="ขงจื๊อ (วจนะ)" +เรียนรู้โดยไร้ความคิดคือเหนื่อยเปล่า ความคิดที่ว่างเปล่าจากการเรียนรู้นั้นเป็นภัย ``` -นักเขียนโปรแกรมนินจาในอดีตใช้เคล็ดลับเหล่านี้เพื่อลับสมองของผู้ดูแลโค้ด +โปรแกรมเมอร์นินจาในอดีตใช้กลเม็ดเหล่านี้เพื่อลับสมองของผู้ดูแลโค้ด -กูรูการรีวิวโค้ดมองหาพวกเขาในงานทดสอบ +ผู้เชี่ยวชาญการรีวิวโค้ดมองหากลเม็ดเหล่านี้ในการทดสอบงาน -นักพัฒนามือใหม่บางครั้งใช้เคล็ดลับเหล่านี้ได้ดีกว่านักโปรแกรมนินจาเสียอีก +บางครั้งนักพัฒนามือใหม่ใช้กลเม็ดเหล่านี้ได้ดีกว่าโปรแกรมเมอร์นินจาเสียอีก -อ่านอย่างถี่ถ้วนและหาว่าคุณเป็นใคร -- นินจา มือใหม่ หรืออาจเป็นผู้รีวิวโค้ด? +อ่านอย่างละเอียดแล้วลองดูว่าคุณเป็นใคร -- นินจา, มือใหม่, หรืออาจเป็นผู้รีวิวโค้ด? -```warn header="ตรวจพบการเสียดสี" -หลายคนพยายามเดินตามเส้นทางของนินจา แต่มีเพียงไม่กี่คนที่ประสบความสำเร็จ +```warn header="พบการเสียดสี" +หลายคนหมายมุ่งวิถีนินจา ทว่าน้อยนักสำเร็จลุล่วงดั่งใจปอง ``` -## ความกระชับเป็นแก่นของไหวพริบ +## ความกระชับคือหัวใจของปัญญา -ทำให้โค้ดสั้นที่สุดเท่าที่จะเป็นไปได้ แสดงให้เห็นว่าคุณฉลาดแค่ไหน +เขียนโค้ดให้สั้นที่สุดเท่าที่จะทำได้ เพื่อแสดงความฉลาดของคุณ -ให้คุณสมบัติภาษาที่ซับซ้อนเป็นแนวทางคุณ +ให้คุณลักษณะภาษาที่ซับซ้อนเป็นตัวนำทาง -ตัวอย่างเช่น ดูที่ตัวดำเนินการแบบสามทางนี้ `'?'`: +ยกตัวอย่างเช่น ลองดูตัวดำเนินการแบบ 3 ทาง (ternary) `'?'` นี้: ```js -// เอามาจากไลบรารี JavaScript ที่มีชื่อเสียงแห่งหนึ่ง +// มาจากไลบรารี JavaScript ที่มีชื่อเสียง i = i ? i < 0 ? Math.max(0, len + i) : i : 0; ``` -เจ๋งใช่ไหม? ถ้าคุณเขียนแบบนี้ นักพัฒนาที่เจอบรรทัดนี้และพยายามเข้าใจว่าค่าของ `i` เป็นเท่าไหร่ จะต้องใช้เวลาสนุกสนาน แล้วจะมาหาคุณเพื่อขอคำตอบ +เจ๋งใช่ไหม? ถ้าคุณเขียนแบบนี้ นักพัฒนาที่เจอบรรทัดนี้และพยายามทำความเข้าใจว่า `i` มีค่าเท่าไหร่ คงจะได้เพลิดเพลิน จากนั้นก็มาหาคุณเพื่อขอคำตอบ -บอกพวกเขาว่าสั้นกว่าดีกว่าเสมอ ฝึกให้พวกเขาสู่เส้นทางนินจา +บอกพวกเขาว่าสั้นกว่าดีกว่าเสมอ แนะนำพวกเขาสู่วิถีแห่งนินจา -## ตัวแปรอักษรตัวเดียว +## ตัวแปรตัวอักษรเดียว ```quote author="เล่าจื๊อ (เต๋าเต๋อจิง)" -เต๋าซ่อนอยู่ในความเงียบงัน มีเพียงเต๋าเท่านั้นที่เริ่มต้นและจบลงอย่างสมบูรณ์ +เต๋าแฝงเร้นในความไร้คำกล่าว เพียงเต๋าเท่านั้นที่เริ่มและจบลงได้ดี ``` -อีกวิธีหนึ่งในการเขียนโค้ดให้สั้นลงคือการใช้ชื่อตัวแปรอักษรเดียวทุกที่ เช่น `a`, `b` หรือ `c` +อีกวิธีหนึ่งที่จะเขียนโค้ดให้สั้นลงคือการใช้ชื่อตัวแปรเพียงตัวอักษรเดียวทุกที่ เช่น `a`, `b` หรือ `c` -ตัวแปรสั้นๆ จะหายไปในโค้ดเหมือนนินจาจริงๆ ในป่า ไม่มีใครหาพบได้ด้วย "ค้นหา" ในเครื่องมือแก้ไขโค้ด และแม้ใครจะเจอ พวกเขาก็จะไม่สามารถ "ถอดรหัส" ได้ว่าชื่อ `a` หรือ `b` หมายถึงอะไร +ตัวแปรที่สั้นจะหายไปในโค้ดเหมือนนินจาในป่า ไม่มีใครสามารถหาเจอได้ด้วยฟีเจอร์ "ค้นหา" ของเครื่องมือแก้ไขโค้ด และถึงแม้ใครจะเจอ พวกเขาก็คงไม่สามารถ "ถอดรหัส" ได้ว่า `a` หรือ `b` หมายถึงอะไร -...แต่มีข้อยกเว้น นินจาแท้จริงจะไม่ใช้ `i` เป็นตัวนับในลูป `"for"` ทุกที่ยกเว้นที่นี่ มองไปรอบๆ มีตัวอักษรแปลกๆ อีกมาก เช่น `x` หรือ `y` +...แต่มีข้อยกเว้น นินจาตัวจริงจะไม่มีวันใช้ `i` เป็นตัวนับในลูป `"for"` ยกเว้นตรงนี้ที่ไหนก็ได้ มองหารอบๆ ดู มีตัวอักษรแปลกๆ อีกมากมาย เช่น `x` หรือ `y` -ตัวแปรแปลกๆ เป็นตัวนับลูปโดยเฉพาะแล้วจะเจ๋งมาก ถ้าเนื้อหาในลูปยาว 1-2 หน้า (ยิ่งยาวยิ่งดี) จากนั้น ถ้ามีใครมองเข้าไปในลูปลึกๆ พวกเขาจะไม่สามารถเดาได้อย่างรวดเร็วว่าตัวแปรที่ชื่อ `x` คือตัวนับของลูป +ใช้ตัวแปรแปลกตาเป็นตัวนับลูปนี่เจ๋งสุดๆ โดยเฉพาะถ้าภายในลูปยาว 1-2 หน้า (ยิ่งยาวยิ่งดี) เพราะถ้ามีใครมาดูโค้ดข้างในลูป พวกเขาจะไม่สามารถเดาได้ในทันทีว่าตัวแปรชื่อ `x` คือตัวนับลูป -## ใช้ตัวย่อ -ถ้ากฎของทีมห้ามใช้ชื่อตัวอักษรเดียวหรือชื่อที่คลุมเครือ -- ย่อมัน ทำเป็นตัวย่อ +## ใช้คำย่อ + +หากกฎของทีมห้ามใช้ชื่อที่เป็นตัวอักษรเดียวหรือคลุมเครือ -- ก็ให้ย่อมัน สร้างคำย่อขึ้นมา แบบนี้: - `list` -> `lst` -- `userAgent` -> `ua` -- `browser` -> `brsr` -- ...เป็นต้น +- `userAgent` -> `ua` +- `browser` -> `brsr` +- ...ฯลฯ -เฉพาะคนที่มีสัญชาตญาณดีจริงๆ เท่านั้นที่จะเข้าใจชื่อเหล่านี้ได้ พยายามย่อทุกอย่าง มีเพียงคนที่คู่ควรเท่านั้นที่จะสามารถสานต่อการพัฒนาโค้ดของคุณ +มีเพียงคนที่มีสัญชาตญาณดีเยี่ยมเท่านั้นที่จะเข้าใจชื่อแบบนี้ได้ พยายามย่อทุกอย่าง มีแต่คนที่เหมาะสมเท่านั้นที่จะสามารถดูแลพัฒนาโค้ดของคุณต่อได้ -## โบยบินสูง เป็นนามธรรม +## โบยบินสูงส่ง ดั่งนามธรรม ```quote author="เล่าจื๊อ (เต๋าเต๋อจิง)" -มุมมนลับเลือน จตุรัสใหญ่ -ภาชนะโล่งว่าง บรรจุความสมบูรณ์ -เสียงท่วงทำนอง ริบหรี่อันไพเราะ -รูปโฉมไร้เงา สะท้อนความยิ่งใหญ่ +สี่เหลี่ยมใหญ่ไร้ซึ่งมุมกำหนด +ภาชนะล้ำค่ารอวันสำเร็จลง +เสียงแห่งพิณน้อยหนึ่งที่กึกก้อง +รูปลักษณ์ยิ่งใหญ่มิอาจสรรหา ``` -ขณะเลือกชื่อ พยายามใช้คำที่เป็นนามธรรมที่สุด เช่น `obj`, `data`, `value`, `item`, `elem` และอื่นๆ +ในการตั้งชื่อ พยายามเลือกใช้คำที่เป็นนามธรรมที่สุด เช่น `obj`, `data`, `value`, `item`, `elem` และอื่นๆ -- **ชื่อในอุดมคติสำหรับตัวแปรคือ `data`** ใช้มันได้ทุกที่ที่ทำได้ แท้จริงแล้วทุกตัวแปรเก็บ *ข้อมูล* ใช่ไหม? +- **`data` คือชื่อตัวแปรในอุดมคติ** ใช้มันทุกที่ที่ทำได้ เพราะตัวแปรทุกตัวมี *ข้อมูล* จริงไหม? - ...แต่ถ้า `data` ถูกใช้ไปแล้วล่ะ? ลองใช้ `value` มันก็ใช้ได้กับทุกอย่างเช่นกัน ในท้ายที่สุด ตัวแปรจะได้รับ *ค่า* + ...แต่ถ้า `data` ถูกใช้ไปแล้วล่ะ? ลองใช้ `value` แทน เพราะมันก็เป็นคำสากลเหมือนกัน ท้ายที่สุดตัวแปรก็มี *ค่า* อยู่ดี -- **ตั้งชื่อตัวแปรตามประเภทของมัน: `str`, `num`...** +- **ตั้งชื่อตัวแปรตามชนิดข้อมูล: `str`, `num`...** - ลองดูสิ ผู้ฝึกหัดมือใหม่อาจสงสัยว่า ชื่อแบบนี้มีประโยชน์จริงๆ สำหรับนินจาหรือ? แน่นอน มีสิ! + ลองใช้ดู มือใหม่อาจสงสัยว่าชื่อแบบนั้นมีประโยชน์จริงหรือสำหรับนินจา? แน่นอน มีประโยชน์จริงๆ! - แน่นอน ชื่อตัวแปรก็ยังหมายความบางอย่าง มันบอกว่าอะไรอยู่ในตัวแปร: สตริง, ตัวเลข หรืออย่างอื่น แต่เมื่อคนนอกพยายามทำความเข้าใจโค้ด พวกเขาจะประหลาดใจที่เห็นว่าจริงๆ แล้วไม่มีข้อมูลอะไรเลย! และในที่สุดก็จะล้มเหลวที่จะเปลี่ยนแปลงโค้ดที่คุณคิดไว้อย่างดี + ชื่อตัวแปรก็ยังพอบอกอะไรได้บ้าง มันบอกว่าข้างในเก็บอะไร: สตริง, ตัวเลข หรืออย่างอื่น แต่ถ้าคนนอกพยายามอ่านโค้ด เขาจะแปลกใจเมื่อพบว่ามันไม่ได้ให้ข้อมูลอะไรเลย! และก็จะแก้โค้ดที่คุณคิดมาอย่างดีไม่ได้สักที - ประเภทของค่านั้นหาได้ง่ายด้วยการดีบั๊ก แต่ความหมายของตัวแปรล่ะ? สตริง/ตัวเลขใดที่มันเก็บไว้? + หาชนิดข้อมูลได้ง่ายโดยการดีบัก แต่ความหมายของตัวแปรล่ะ? มันเก็บสตริง/ตัวเลขอะไรกันแน่? - ไม่มีทางรู้ได้เลยหากไม่ใช้สมาธิที่ดี! + ไม่มีทางรู้ได้เลย นอกจากจะทำสมาธิให้ดี! -- **...แต่ถ้าไม่มีชื่อแบบนี้แล้วล่ะ?** ก็แค่เพิ่มตัวเลข: `data1, item2, elem5`... +- **...แล้วถ้าชื่อแบบนั้นไม่เหลือแล้วล่ะ?** ก็แค่เติมตัวเลขต่อท้าย: `data1, item2, elem5`... -## การทดสอบความใส่ใจ +## ทดสอบความใส่ใจ -มีเพียงโปรแกรมเมอร์ที่ตั้งใจจริงๆ เท่านั้นที่จะเข้าใจโค้ดของคุณได้ แต่จะตรวจสอบได้อย่างไร? +มีแค่โปรแกรมเมอร์ที่ใส่ใจจริงๆ เท่านั้นถึงจะเข้าใจโค้ดของคุณได้ แต่จะตรวจสอบได้ยังไง? -**หนึ่งในวิธี -- ใช้ชื่อตัวแปรที่คล้ายกัน เช่น `date` และ `data`** +**หนึ่งในวิธีคือใช้ชื่อตัวแปรที่คล้ายกัน เช่น `date` กับ `data`** -ผสมมันในที่ที่ทำได้ +ใช้สลับกันไปมาตามที่ทำได้ -การอ่านโค้ดแบบนี้อย่างรวดเร็วเป็นไปไม่ได้ และเมื่อมีการพิมพ์ผิด... อืมม์... เราก็ติดกับดักนาน ได้เวลาดื่มชากันแล้ว +การอ่านโค้ดผ่านๆ จะเป็นไปไม่ได้เลย แล้วถ้ามีการพิมพ์ผิดอีก... อืม... คงได้ติดอยู่กับมันนาน ถึงเวลาไปดื่มชากันแล้ว -## คำพ้องความหมายอัจฉริยะ +## คำพ้องความหมาย -```quote author="เล่าจื๊อ (เต๋าเต๋อจิง)" -เต๋าอันแท้จริงไร้ถ้อยใดบรรยาย นามอันแท้จริงไร้ชื่อใดเรียกขาน +```quote author="เล่าจื๊อ (เต๋าเต๋อจิง)" +เต๋าที่เล่าได้มิใช่เต๋าอมตะ นามที่เอ่ยขานมิใช่นามนิรันดร์ ``` -การใช้ชื่อที่*คล้ายกัน*สำหรับสิ่งที่*เหมือนกัน* ทำให้ชีวิตน่าสนใจยิ่งขึ้นและแสดงความคิดสร้างสรรค์ของคุณต่อสาธารณะ +การใช้ชื่อ *คล้ายๆ กัน* กับสิ่งที่ *เหมือนๆ กัน* ทำให้ชีวิตสนุกขึ้น และแสดงความคิดสร้างสรรค์ของคุณให้คนอื่นเห็น -ตัวอย่างเช่น พิจารณาคำนำหน้าฟังก์ชัน ถ้าฟังก์ชันแสดงข้อความบนหน้าจอ -- เริ่มต้นด้วย `display…` เช่น `displayMessage` และถ้าฟังก์ชันอื่นแสดงอย่างอื่นบนหน้าจอ เช่นชื่อผู้ใช้ ให้เริ่มต้นด้วย `show…` (เช่น `showName`) +เช่น คำนำหน้าฟังก์ชัน ถ้าฟังก์ชันแสดงข้อความบนจอ ให้ขึ้นต้นด้วย `display...` อย่าง `displayMessage` แล้วถ้ามีอีกฟังก์ชันที่แสดงอย่างอื่นบนจอ เช่นชื่อผู้ใช้ ก็ขึ้นต้นด้วย `show...` แทน (อย่าง `showName`) -บอกเป็นนัยว่ามีความแตกต่างเล็กน้อยระหว่างฟังก์ชันดังกล่าว แต่จริงๆ แล้วไม่มี +ทำให้รู้สึกเหมือนมันมีความต่างแบบประณีต ทั้งที่จริงๆ ไม่ได้ต่างกันเลย -ทำข้อตกลงกับนินจาในทีม: ถ้า John เริ่ม "แสดง" ฟังก์ชันด้วย `display...` ในโค้ดของเขา แล้ว Peter อาจใช้ `render..` และ Ann -- `paint...` สังเกตว่าโค้ดน่าสนใจและหลากหลายขึ้นมากแค่ไหน +ทำสัญญากับเพื่อนนินจาในทีมว่า ถ้าจอห์นเริ่มฟังก์ชัน "แสดง" ด้วย `display...` ในโค้ดของเขา ปีเตอร์จะใช้ `render...` ส่วนแอนใช้ `paint...` สังเกตว่าโค้ดจะน่าสนใจและหลากหลายมากขึ้นแค่ไหน -...และตอนนี้เทคนิคเด็ด! +...แล้วนี่คือไม้เด็ด! -สำหรับฟังก์ชันสองตัวที่มีความแตกต่างสำคัญ -- ใช้คำนำหน้าเดียวกัน! +สำหรับสองฟังก์ชันที่แตกต่างกันชัดเจน ให้ใช้คำนำหน้าเดียวกัน! -ตัวอย่างเช่น ฟังก์ชัน `printPage(page)` จะใช้เครื่องพิมพ์ และฟังก์ชัน `printText(text)` จะวางข้อความบนหน้าจอ ให้ผู้อ่านที่ไม่คุ้นเคยคิดให้ดีเกี่ยวกับฟังก์ชัน `printMessage` ที่ตั้งชื่อคล้ายกัน: "มันวางข้อความไว้ที่ไหน? ในเครื่องพิมพ์หรือบนหน้าจอ?" ในการทำให้มันเจิดจริงๆ `printMessage(message)` ควรแสดงผลมันในหน้าต่างใหม่! +อย่างเช่น ฟังก์ชัน `printPage(page)` จะส่งไปเครื่องพิมพ์ ส่วน `printText(text)` จะแสดงข้อความบนจอ ให้คนอ่านที่ไม่คุ้นคิดหนักกับฟังก์ชัน `printMessage` ที่มีชื่อคล้ายๆ กันว่า "มันส่งข้อความไปไหนนะ เครื่องพิมพ์หรือบนจอ?" จะเจ๋งขึ้นไปอีกถ้า `printMessage(message)` แสดงผลในหน้าต่างใหม่! -## นำชื่อกลับมาใช้ใหม่ +## ใช้ชื่อซ้ำ ```quote author="เล่าจื๊อ (เต๋าเต๋อจิง)" -เมื่อองค์รวมแยกสลาย -สรรพสิ่งล้วนปรากฏนาม -นามมากมายล้นหลาม -ควรหยุดยั้งเมื่อพอดี +เมื่อแบ่งสรรพสิ่งออกเป็นส่วนย่อย +แต่ละส่วนล้วนต้องการชื่อเรียกขาน +นามทั้งหลายมีอยู่มากมายแล้ว +รู้จักพอคือคุณูปการอันล้ำค่า ``` -เพิ่มตัวแปรใหม่ก็ต่อเมื่อจำเป็นจริงๆ เท่านั้น +อย่าเพิ่มตัวแปรใหม่ถ้าไม่จำเป็นจริงๆ -แทนที่จะทำแบบนั้น ให้นำชื่อที่มีอยู่แล้วกลับมาใช้ใหม่ เพียงแค่เขียนค่าใหม่ลงไปในตัวแปรเหล่านั้น +แทนที่จะทำแบบนั้น ให้นำชื่อที่มีอยู่แล้วมาใช้ใหม่ แค่เขียนค่าใหม่ลงไปแทนที่ค่าเดิม -ในฟังก์ชัน พยายามใช้เฉพาะตัวแปรที่ส่งเข้ามาเป็นพารามิเตอร์ +ภายในฟังก์ชัน พยายามใช้เฉพาะตัวแปรที่ส่งเข้ามาเป็นพารามิเตอร์เท่านั้น -นั่นจะทำให้ยากจริงๆ ที่จะระบุว่ามีอะไรอยู่ในตัวแปร *ตอนนี้* และมาจากที่ไหน จุดประสงค์คือการพัฒนาสัญชาตญาณและความจำของคนที่อ่านโค้ด คนที่มีสัญชาตญาณอ่อนแอจะต้องวิเคราะห์โค้ดทีละบรรทัดและติดตามการเปลี่ยนแปลงผ่านทุกสาขาของโค้ด +วิธีนี้จะทำให้แทบเป็นไปไม่ได้เลยที่จะระบุได้ว่าอะไรอยู่ในตัวแปร *ตอนนี้* และมาจากไหน จุดประสงค์คือเพื่อฝึกสัญชาตญาณและความจำของคนที่อ่านโค้ด คนที่สัญชาตญาณไม่ดีจะต้องวิเคราะห์โค้ดทีละบรรทัดและติดตามการเปลี่ยนแปลงข้ามทุกการแตกแขนงของโค้ด -**ตัวแปรขั้นสูงของวิธีนี้คือการแอบ (!) แทนที่ค่าด้วยอะไรที่คล้ายๆ กันในระหว่างลูปหรือฟังก์ชัน** +**รูปแบบขั้นสูงของวิธีนี้คือการแอบ (!) เปลี่ยนค่าเป็นอย่างอื่นที่คล้ายๆ กันระหว่างวนลูปหรือทำงานในฟังก์ชัน** ตัวอย่างเช่น: ```js function ninjaFunction(elem) { - // 20 บรรทัดโค้ดทำงานกับ elem + // 20 บรรทัดโค้ดที่ทำงานกับ elem elem = clone(elem); - // อีก 20 บรรทัด ตอนนี้ทำงานกับโคลนของ elem! + // อีก 20 บรรทัด ตอนนี้ทำงานกับ clone ของ elem! } ``` -โปรแกรมเมอร์เพื่อนร่วมงานที่ต้องการทำงานกับ `elem` ในครึ่งหลังของฟังก์ชันจะประหลาดใจ... จนกระทั่งระหว่างดีบั๊ก หลังจากตรวจสอบโค้ดแล้วพวกเขาจะพบว่ากำลังทำงานกับโคลน! +โปรแกรมเมอร์ที่ต้องการทำงานกับ `elem` ในครึ่งหลังของฟังก์ชันจะงงแน่ๆ... จนกว่าจะลองดีบักและไล่ดูโค้ด ถึงจะรู้ว่ากำลังทำงานกับตัวโคลนอยู่! -เห็นในโค้ดเป็นประจำ มีประสิทธิภาพถึงตายแม้กระทั่งกับนินจาที่มีประสบการณ์ +เจอแบบนี้ในโค้ดบ่อยมาก ได้ผลดีถึงตายแม้กับนินจาจอมเก๋า -## ขีดล่างเพื่อความสนุก +## ใช้ underscore ให้สนุก -ใส่ขีดล่าง `_` และ `__` ไว้ข้างหน้าชื่อตัวแปร เช่น `_name` หรือ `__value` จะดีมากถ้ามีแค่คุณเท่านั้นที่รู้ความหมายของพวกมัน หรือที่ดีกว่านั้น เพิ่มพวกมันเข้าไปเพื่อความสนุกเฉยๆ โดยไม่มีความหมายอะไรเป็นพิเศษเลย หรือความหมายที่แตกต่างกันในที่ต่างๆ +ใส่ underscore `_` และ `__` ข้างหน้าชื่อตัวแปร เช่น `_name` หรือ `__value` ถ้ามีแค่คุณที่รู้ความหมายคงจะดีมาก หรือดีกว่านั้น ใส่มันลงไปเพื่อความสนุกเฉยๆ โดยไม่มีความหมายพิเศษอะไรเลย หรือมีความหมายต่างกันในแต่ละที่ก็ได้ -คุณฆ่ากระต่ายสองตัวด้วยหนึ่งนัด ประการแรก โค้ดจะยาวขึ้นและอ่านยากขึ้น และประการที่สอง นักพัฒนาเพื่อนร่วมงานอาจใช้เวลานานในการพยายามคิดว่าขีดล่างหมายถึงอะไร +คุณจะฆ่าสองนกในหินก้อนเดียว หนึ่ง โค้ดจะยาวขึ้นและอ่านยากขึ้น และสอง เพื่อนนักพัฒนาอาจเสียเวลาไปเยอะกับการพยายามหาว่า underscore หมายถึงอะไร -นินจาฉลาดวางขีดล่างในจุดหนึ่งของโค้ดและหลบเลี่ยงมันในอีกที่ นั่นทำให้โค้ดเปราะบางยิ่งขึ้นและเพิ่มโอกาสที่จะเกิดข้อผิดพลาดในอนาคต +นินจาเก๋าจะวาง underscore ไว้ที่หนึ่งในโค้ด แล้วไม่ใส่อีกที่นึง นั่นจะยิ่งทำให้โค้ดเปราะบางและเพิ่มโอกาสเกิดข้อผิดพลาดในอนาคต -## แสดงความรักของคุณ +## แสดงความรัก -ให้ทุกคนเห็นว่า entities ของคุณยิ่งใหญ่แค่ไหน! ชื่อเช่น `superElement`, `megaFrame` และ `niceItem` จะทำให้ผู้อ่านตาสว่างอย่างแน่นอน +ให้ทุกคนได้เห็นความวิเศษของ entity ต่างๆ ของคุณ! ชื่อเช่น `superElement`, `megaFrame` และ `niceItem` จะทำให้ผู้อ่านรู้สึกเปล่งประกายแน่ๆ -แน่นอน จากด้านหนึ่ง มีบางอย่างเขียนอยู่: `super..`, `mega..`, `nice..` แต่อีกด้านหนึ่ง -- มันไม่ได้ให้รายละเอียดอะไรเลย ผู้อ่านอาจตัดสินใจมองหาความหมายที่ซ่อนอยู่และนั่งสมาธิสักชั่วโมงสองชั่วโมงของเวลาทำงานที่ได้รับค่าจ้าง +ก็จริงอยู่ มีอะไรบางอย่างถูกเขียนไว้: `super..`, `mega..`, `nice..` แต่ในอีกแง่หนึ่ง มันก็ไม่ได้ให้รายละเอียดอะไรเลย ผู้อ่านอาจตัดสินใจค้นหาความหมายที่ซ่อนอยู่และนั่งสมาธิสักชั่วโมงสองชั่วโมงในเวลางานที่ได้ค่าจ้าง -## ทับตัวแปรภายนอก +## ใช้ชื่อซ้ำกับตัวแปรด้านนอก ```quote author="กวนอินจื้อ" -เมื่ออยู่ในแสง จะมองไม่เห็นอะไรในความมืด -เมื่ออยู่ในความมืด จะมองเห็นทุกอย่างในแสง +ยามพำนักในแสงสว่างมิอาจมองเห็นความมืดมน +ครั้นแล้วเมื่อเข้าสู่ความมืดกลับเห็นทุกสิ่งในแสงสว่าง ``` -ใช้ชื่อเดียวกันสำหรับตัวแปรภายในและภายนอกฟังก์ชัน ง่ายมาก ไม่ต้องพยายามคิดชื่อใหม่ +ใช้ชื่อเดียวกันสำหรับตัวแปรทั้งในและนอกฟังก์ชัน แค่นี้แหละ ไม่ต้องพยายามคิดชื่อใหม่ ```js let *!*user*/!* = authenticateUser(); @@ -183,50 +184,50 @@ function render() { ... ...หลายบรรทัด... ... - ... // <-- โปรแกรมเมอร์ต้องการใช้งานกับ user ที่นี่และ... + ... // <-- โปรแกรมเมอร์อยากทำงานกับ user ตรงนี้และ... ... } ``` -โปรแกรมเมอร์ที่กระโดดเข้าไปใน `render` อาจจะไม่สังเกตเห็นว่ามี `user` ภายในที่บดบัง `user` ภายนอกอยู่ +โปรแกรมเมอร์ที่ข้ามเข้ามาใน `render` อาจไม่ทันสังเกตว่ามี `user` ในฟังก์ชันกำลังบดบัง `user` ด้านนอกอยู่ -แล้วพวกเขาจะพยายามทำงานกับ `user` โดยคิดว่ามันคือตัวแปรภายนอก ซึ่งเป็นผลมาจาก `authenticateUser()`... กับดักถูกวางไว้! สวัสดี debugger... +แล้วเขาจะพยายามทำงานกับ `user` โดยคิดว่ามันคือตัวแปรจากภายนอก ซึ่งเป็นผลลัพธ์จาก `authenticateUser()` ... กับดักถูกปล่อยแล้ว! สวัสดี debugger ... -## ผลข้างเคียง (Side-effects) ทุกหนทุกแห่ง! +## ผลข้างเคียงได้ทุกที่! -มีฟังก์ชันที่ดูเหมือนไม่ได้เปลี่ยนแปลงอะไร เช่น `isReady()`, `checkPermission()`, `findTags()`... พวกมันถูกสมมติว่าจะทำการคำนวณ ค้นหาและส่งข้อมูลกลับ โดยไม่เปลี่ยนแปลงอะไรภายนอก หรือก็คือไม่มี "ผลข้างเคียง" +มีฟังก์ชันบางอย่างที่ดูเหมือนไม่ได้เปลี่ยนแปลงอะไรเลย เช่น `isReady()`, `checkPermission()`, `findTags()` ... มักคาดหวังว่าฟังก์ชันพวกนี้จะคำนวณ ค้นหา และคืนข้อมูล โดยไม่แปรเปลี่ยนสิ่งใดภายนอก หรือก็คือ ไม่มี "ผลข้างเคียง" -**เคล็ดลับที่สวยงามจริงๆ คือการเพิ่มการกระทำที่ "มีประโยชน์" เข้าไปในนั้น นอกเหนือจากงานหลัก** +**กลเม็ดสุดเจ๋งคือแอบใส่การกระทำที่ "มีประโยชน์" เข้าไป นอกเหนือจากงานหลัก** -สีหน้าประหลาดใจอึ้งๆ บนใบหน้าของเพื่อนร่วมงานเมื่อพวกเขาเห็นฟังก์ชันชื่อ `is..`, `check..` หรือ `find...` ที่เปลี่ยนแปลงบางอย่าง -- จะขยายขอบเขตเหตุผลของคุณอย่างแน่นอน +สีหน้าประหลาดใจงงงวยของเพื่อนร่วมงาน เมื่อเห็นฟังก์ชันชื่อ `is..`, `check..` หรือ `find...` ที่ดันไปเปลี่ยนแปลงอะไรบางอย่าง จะช่วยขยายขอบเขตความคิดของคุณแน่นอน -**อีกวิธีในการทำให้ประหลาดใจคือการส่งผลลัพธ์ที่ไม่ได้มาตรฐานกลับ** +**อีกวิธีที่จะสร้างความประหลาดใจคือส่งคืนผลลัพธ์แบบไม่ปกติ** -แสดงความคิดริเริ่มของคุณ! ให้การเรียก `checkPermission` ส่งกลับไม่ใช่ `true/false` แต่เป็นออบเจ็กต์ที่ซับซ้อนพร้อมกับผลการตรวจสอบ +แสดงความคิดริเริ่มของคุณ! ให้ `checkPermission` คืนค่าไม่ใช่แค่ `true/false` แต่เป็นอ็อบเจ็กต์ที่ซับซ้อนพร้อมผลการตรวจสอบ -นักพัฒนาที่พยายามเขียน `if (checkPermission(..))` จะสงสัยว่าทำไมมันถึงไม่ทำงาน บอกพวกเขาว่า: "อ่านเอกสารสิ!" และให้บทความนี้ +นักพัฒนาที่พยายามเขียน `if (checkPermission(..))` จะสงสัยว่าทำไมมันถึงใช้ไม่ได้ บอกพวกเขาไปเลยว่า "อ่านเอกสารกำกับสิ!" แล้วก็ส่งลิงก์บทความนี้ให้ -## ฟังก์ชันทรงพลัง! +## ฟังก์ชันอันทรงพลัง! -```quote author="เล่าจื๊อ (เต้าเต๋อจิง)" -มหาเต๋าไหลลื่นทั่วทุกหน -ทั้งซ้ายขวา ไร้ขีดคั่น +```quote author="เล่าจื๊อ (เต๋าเต๋อจิง)" +เต๋าใหญ่ยิ่งไหลทั่วทุกหนแห่ง +ทั้งซ้ายและขวาล้วนซาบซ่านเต็มเปี่ยม ``` -อย่าจำกัดฟังก์ชันด้วยสิ่งที่เขียนไว้ในชื่อของมัน คิดให้กว้างขึ้น +อย่าจำกัดฟังก์ชันด้วยสิ่งที่เขียนไว้ในชื่อของมัน จงมองให้กว้างไกลกว่านั้น -ตัวอย่างเช่น ฟังก์ชัน `validateEmail(email)` สามารถ (นอกเหนือจากการตรวจสอบความถูกต้องของอีเมล) แสดงข้อความแสดงข้อผิดพลาดและขอให้ป้อนอีเมลใหม่ได้ +ยกตัวอย่างเช่น ฟังก์ชัน `validateEmail(email)` อาจแสดงข้อผิดพลาดและขอให้กรอกอีเมลใหม่ด้วย (นอกเหนือจากการตรวจสอบความถูกต้องของอีเมล) -การกระทำเพิ่มเติมไม่ควรเห็นได้ชัดเจนจากชื่อฟังก์ชัน นินจาโค้ดเดอร์ตัวจริงจะทำให้พวกมันไม่ชัดเจนจากโค้ดเช่นกัน +การกระทำเพิ่มเติมไม่ควรชัดเจนจากชื่อฟังก์ชัน นินจาเขียนโค้ดตัวจริงจะทำให้มองไม่ออกจากในโค้ดเช่นกัน -**การรวมหลายการกระทำเข้าด้วยกันจะปกป้องโค้ดของคุณจากการนำกลับมาใช้ใหม่** +**การรวมหลายการกระทำเข้าด้วยกันจะปกป้องโค้ดของคุณจากการนำไปใช้ซ้ำ** -ลองจินตนาการว่า นักพัฒนาอีกคนต้องการแค่ตรวจสอบอีเมล ไม่ใช่แสดงข้อความใดๆ ฟังก์ชัน `validateEmail(email)` ของคุณที่ทำทั้งสองอย่างจะไม่เหมาะกับพวกเขา ดังนั้นพวกเขาจะไม่รบกวนสมาธิของคุณด้วยการถามอะไรเกี่ยวกับมัน +สมมติว่ามีนักพัฒนาอีกคนต้องการแค่เช็คอีเมลเฉยๆ โดยไม่ต้องแสดงข้อความใดๆ ฟังก์ชัน `validateEmail(email)` ของคุณที่ทำงานทั้งสองอย่างจะไม่เหมาะกับเขา แบบนี้เขาจะไม่มารบกวนสมาธิของคุณด้วยการมาถามคำถามใดๆ เกี่ยวกับมัน ## สรุป -ทุก "คำแนะนำ" ข้างต้นมาจากโค้ดจริง... บางครั้งเขียนโดยนักพัฒนาที่มีประสบการณ์ บางทีอาจจะมีประสบการณ์มากกว่าคุณด้วยซ้ำ ;) +"เคล็ดลับ" ข้างต้นทั้งหมดมาจากโค้ดของจริง... บางครั้งเขียนโดยนักพัฒนาผู้มากประสบการณ์ บางทีอาจจะมากกว่าคุณด้วยซ้ำ ;) - ทำตามบางข้อ และโค้ดของคุณจะเต็มไปด้วยเรื่องน่าประหลาดใจ -- ทำตามหลายๆ ข้อ และโค้ดของคุณจะกลายเป็นของคุณจริงๆ ไม่มีใครอยากเปลี่ยนแปลงมัน -- ทำตามทุกข้อ และโค้ดของคุณจะกลายเป็นบทเรียนอันล้ำค่าสำหรับนักพัฒนารุ่นใหม่ที่กำลังมองหาการรู้แจ้ง +- ทำตามหลายๆ ข้อ และโค้ดจะกลายเป็นของคุณโดยแท้จริง ไม่มีใครอยากเปลี่ยนแปลงมัน +- ทำตามทุกข้อ และโค้ดของคุณจะกลายเป็นบทเรียนอันล้ำค่าสำหรับนักพัฒนาหน้าใหม่ผู้แสวงหาการรู้แจ้ง \ No newline at end of file