diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md index 581d777c9..b233092e4 100644 --- a/1-js/02-first-steps/04-variables/article.md +++ b/1-js/02-first-steps/04-variables/article.md @@ -1,61 +1,61 @@ # ตัวแปร -ส่วนใหญ่แอปพลิเคชัน JavaScript จำเป็นต้องทำงานกับข้อมูล ต่อไปนี้เป็นตัวอย่างสองแอพที่เราคุ้นเคยกัน: -1. ร้านค้าออนไลน์ - ข้อมูลอาจจะรวมถึงสินค้าที่ขายและรถเข็นสินค้า -2. แอปพลิเคชันแชท - ข้อมูลอาจจะรวมถึงผู้ใช้ ข้อความ และอื่นๆอีกมากมาย +ในการพัฒนาแอปพลิเคชัน JavaScript ส่วนใหญ่ เรามักจะต้องทำงานกับข้อมูล ยกตัวอย่างเช่น +1. ร้านค้าออนไลน์ -- ข้อมูลอาจประกอบด้วยสินค้าที่จำหน่ายและตะกร้าสินค้า +2. แอปพลิเคชันแชท -- ข้อมูลอาจประกอบด้วยผู้ใช้ ข้อความ และอื่นๆ อีกมากมาย -ตัวแปรจะถูกใช้เพื่อจัดเก็บข้อมูลนี้ +ตัวแปรถูกใช้เพื่อจัดเก็บข้อมูลเหล่านี้ -## ตัวแปร +## ตัวแปรคืออะไร -[ตัวแปร](https://en.wikipedia.org/wiki/Variable_(computer_science)) เป็น "ที่เก็บข้อมูลที่มีชื่อ" เราสามารถใช้ตัวแปรเพื่อเก็บสิ่งที่สนใจ, ผู้เยี่ยมชม, และข้อมูลอื่นๆ +[ตัวแปร](https://en.wikipedia.org/wiki/Variable_(computer_science)) คือ "พื้นที่จัดเก็บข้อมูลที่มีชื่อกำกับ" เราสามารถใช้ตัวแปรเพื่อเก็บสินค้า ข้อมูลผู้เยี่ยมชม และข้อมูลอื่นๆ ได้ -การสร้างตัวแปรใน JavaScript, เราใช้คีย์เวิร์ด `let` +ในการสร้างตัวแปรใน JavaScript ให้ใช้คีย์เวิร์ด `let` -คำสั่งด้านล่างนี้สร้าง (หรือเรียกอีกอย่างหนึ่งว่า: *ประกาศ (declares)*) ตัวแปรที่มีชื่อว่า "message": +คำสั่งด้านล่างจะสร้าง (หรือที่เรียกอีกอย่างว่า *ประกาศ*) ตัวแปรที่มีชื่อว่า "message": ```js let message; ``` -ตอนนี้, เราสามารถใส่ข้อมูลลงไปในมันด้วยการใช้ตัวดำเนินการกำหนดค่า (assignment operator) `=`: +ตอนนี้เราสามารถใส่ข้อมูลลงในตัวแปรได้ด้วยการใช้เครื่องหมาย `=` หรือที่เรียกว่าตัวดำเนินการกำหนดค่า (assignment operator): ```js let message; *!* -message = 'สวัสดี'; // เก็บสตริง 'สวัสดี' ลงในตัวแปรที่ชื่อ message +message = 'สวัสดี'; // เก็บข้อความ 'สวัสดี' ในตัวแปรที่ชื่อว่า message */!* ``` -สตริงถูกบันทึกลงในพื้นที่หน่วยความจำที่เชื่อมโยงกับตัวแปร ที่เราสามารถเข้าถึงสตริงนี้ได้โดยใช้ชื่อตัวแปร: +ข้อความนี้จะถูกบันทึกลงในพื้นที่หน่วยความจำที่สัมพันธ์กับตัวแปร และเราสามารถเข้าถึงข้อมูลนี้ได้ด้วยการอ้างอิงชื่อตัวแปร: ```js run let message; message = 'สวัสดี!'; *!* -alert(message); // แสดงเนื้อหาของตัวแปร +alert(message); // แสดงค่าในตัวแปร */!* ``` -เพื่อความกระชับ, เราสามารถรวมการประกาศตัวแปรและการกำหนดค่าเข้าด้วยกันในบรรทัดเดียว: +เพื่อความกระชับ เราสามารถรวมการประกาศตัวแปรและกำหนดค่าเริ่มต้นไว้ในบรรทัดเดียวกันได้: ```js run -let message = 'สวัสดี!'; // กำหนดตัวแปรและกำหนดค่า +let message = 'สวัสดี!'; // ประกาศตัวแปรและกำหนดค่าในคำสั่งเดียว alert(message); // สวัสดี! ``` -เรายังสามารถประกาศตัวแปรหลายตัวในบรรทัดเดียว: +นอกจากนี้ เรายังสามารถประกาศตัวแปรหลายตัวในบรรทัดเดียวได้ด้วย: ```js no-beautify let user = 'จอห์น', age = 25, message = 'สวัสดี'; ``` -ที่อาจดูสั้นกว่า, แต่เราไม่แนะนำ เพื่อให้อ่านได้อ่านขึ้น, เราแนะนำว่าควรประกาศหนึ่งตัวแปรต่อหนึ่งบรรทัด +วิธีนี้อาจจะดูสั้นกระชับดี แต่เราไม่แนะนำให้ใช้ เพื่อความสะดวกในการอ่านโค้ด ควรประกาศตัวแปรแต่ละตัวแยกเป็นคนละบรรทัดจะดีกว่า -แบบที่มีหลายบรรทัดนั้นยาวขึ้นนิดหน่อย, แต่ง่ายต่อการอ่าน: +แบบนี้อาจยาวกว่าเล็กน้อย แต่อ่านง่ายขึ้นมาก: ```js let user = 'จอห์น'; @@ -63,7 +63,7 @@ let age = 25; let message = 'สวัสดี'; ``` -บางคนยังกำหนดตัวแปรหลายตัวในรูปแบบที่มีหลายบรรทัดนี้: +บางคนยังชอบประกาศตัวแปรหลายตัวแบบหลายบรรทัดแบบนี้: ```js no-beautify let user = 'จอห์น', @@ -71,7 +71,7 @@ let user = 'จอห์น', message = 'สวัสดี'; ``` -...หรือแม้กระทั่งในรูปแบบ "comma-first": +หรือแม้กระทั่งเขียนในรูปแบบ "เริ่มต้นด้วยเครื่องหมายจุลภาค": ```js no-beautify let user = 'จอห์น' @@ -79,195 +79,198 @@ let user = 'จอห์น' , message = 'สวัสดี'; ``` -จากทางเทคนิค, ทุกๆ รูปแบบนี้ทำงานเหมือนกัน ดังนั้น, มันเป็นเรื่องของรสนิยมส่วนบุคคลและความสวยงามของโค้ด +ในเชิงเทคนิคแล้ว ตัวแปรทั้งหมดที่ยกตัวอย่างมาทำงานในลักษณะเดียวกัน จึงเป็นเรื่องของรสนิยมและความชอบส่วนตัว -````smart header="`var` แทน `let`" -ในสคริปต์ที่เก่ากว่า เราอาจจะพบคีย์เวิร์ดอื่น: `var` แทน `let`: +````smart header="`var` กับ `let`" +ในสคริปต์เก่าๆ คุณอาจเจอการใช้คีย์เวิร์ด `var` แทน `let` ในการประกาศตัวแปร: ```js *!*var*/!* message = 'สวัสดี'; ``` -คีย์เวิร์ด `var` นั้น *แทบจะ* เหมือนกับ `let` มันคือประกาศตัวแปรเหมือนกัน แต่มันแบบเก่า +คีย์เวิร์ด `var` นั้น*เกือบจะ*เหมือนกับ `let` คือใช้ประกาศตัวแปร แต่จะมีความแตกต่างเล็กน้อยในสไตล์ที่ค่อนข้าง "เชย" -มีความแตกต่างที่ละเอียดระหว่าง `let` และ `var` แต่ไม่สำคัญสำหรับเราในขณะนี้ เราจะพูดถึงเรื่องนี้อย่างละเอียดในบท +ความแตกต่างระหว่าง `let` กับ `var` นั้นไม่ใช่ประเด็นสำคัญสำหรับเราในตอนนี้ เราจะกล่าวถึงรายละเอียดในบทเรียน + +โดยทั่วไปแล้ว ในโค้ด JavaScript สมัยใหม่เรามักใช้ `let` ในการประกาศตัวแปร ส่วนการใช้ `var` ถือเป็นวิธีการแบบเดิมที่ปัจจุบันไม่เป็นที่นิยมแล้ว ```` -## หากเทียบกับชีวิตจริง +# การเปรียบเทียบกับสถานการณ์ในชีวิตจริง -เราสามารถเข้าใจแนวคิดของ "ตัวแปร" ได้ง่ายหากเราจินตนาการว่ามันคือ "กล่อง" สำหรับข้อมูล, มีสติ๊กเกอร์ที่มีชื่อที่ไม่ซ้ำกันติดอยู่บนกล่อง +เราสามารถเข้าใจแนวคิดของ "ตัวแปร" ได้ง่ายขึ้น ถ้าลองนึกภาพว่ามันเป็น "กล่อง" ไว้ใส่ข้อมูล โดยมีสติกเกอร์ชื่อเฉพาะติดอยู่ -ตัวอย่างเช่น ตัวแปร `message` สามารถจินตนาการได้ว่าเป็นกล่องที่มีป้ายชื่อ `"message"` และมีค่า `"สวัสดี!"` อยู่ในกล่อง: +ยกตัวอย่างเช่น ตัวแปร `message` จะเปรียบได้กับกล่องที่มีป้ายชื่อ `"message"` และมีค่า `"สวัสดี!"` ข้างใน: ![](variable.svg) -เราสามารถใส่ค่าอะไรก็ได้ลงในกล่อง +เราสามารถใส่ค่าอะไรก็ได้ลงในกล่องนี้ -เรายังสามารถเปลี่ยนแปลงค่าในกล่องได้เท่าที่เราต้องการ: +และเปลี่ยนค่าได้ตามใจชอบ: ```js run let message; message = 'สวัสดี!'; -message = 'โลก!'; // ค่าถูกเปลี่ยน +message = 'ชาวโลก!'; // เปลี่ยนค่าแล้ว alert(message); ``` -เมื่อค่าถูกเปลี่ยน ข้อมูลเก่าจะถูกลบออกจากตัวแปร: +เวลาเปลี่ยนค่า ข้อมูลเก่าจะถูกนำออกจากตัวแปรไป: ![](variable-change.svg) -เรายังสามารถประกาศตัวแปรสองตัวและคัดลอกข้อมูลจากตัวหนึ่งไปยังอีกตัวหนึ่ง +นอกจากนี้ เรายังสามารถประกาศตัวแปรสองตัว แล้วคัดลอกข้อมูลจากตัวหนึ่งไปอีกตัวหนึ่งได้ด้วย ```js run -let hello = 'สวัสดี โลก!'; +let hello = 'สวัสดีชาวโลก!'; let message; *!* -// คัดลอก 'สวัสดี โลก!' จาก hello ไปยัง message +// คัดลอก 'สวัสดีชาวโลก!' จาก hello มาเก็บใน message message = hello; */!* -// ตอนนี้มีตัวแปรสองตัวที่เก็บข้อมูลเดียวกัน -alert(hello); // สวัสดี โลก! -alert(message); // สวัสดี โลก! +// ตอนนี้ตัวแปรทั้งสองมีข้อมูลชุดเดียวกัน +alert(hello); // สวัสดีชาวโลก! +alert(message); // สวัสดีชาวโลก! ``` -````warn header="ประกาศตัวแปรซ้ำกันจะทำให้เกิดข้อผิดพลาด" -ตัวแปรควรถูกประกาศเพียงครั้งเดียว +````warn header="การประกาศตัวแปรซ้ำจะเกิดข้อผิดพลาด" +ควรประกาศตัวแปรเพียงครั้งเดียวเท่านั้น -การประกาศตัวแปรเดิมซ้ำๆจะเป็นข้อผิดพลาด: +หากประกาศตัวแปรเดิมซ้ำอีก จะถือเป็นข้อผิดพลาด: ```js run -let message = "นี้"; +let message = "นี่"; -// 'let' ประกาศคัวแปรเดิมซ้ำจะนำไปสู่ข้อผิดพลาด -let message = "นั่น"; // SyntaxError: 'message' ถูกประกาศแล้ว +// ประกาศ 'let' ซ้ำ ทำให้เกิด error +let message = "นั่น"; // SyntaxError: 'message' ถูกประกาศไปแล้ว ``` -ดังนั้น, เราควรประกาศตัวแปรครั้งเดียวแล้วจึงอ้างอิงถึงมันโดยไม่ต้องใช้ `let`. + +ดังนั้น เราควรประกาศตัวแปรแค่ครั้งเดียว จากนั้นก็อ้างอิงถึงมันได้เลยโดยไม่ต้องมี `let` อีก ```` ```smart header="ภาษาการเขียนโปรแกรมแบบฟังก์ชัน" -น่าสนใจที่จะทราบว่ามีภาษาการเขียนโปรแกรมแบบ [pure functional](https://en.wikipedia.org/wiki/Purely_functional_programming) ที่ห้ามการเปลี่ยนแปลงค่าของตัวแปร, เช่น [Haskell](https://en.wikipedia.org/wiki/Haskell) +น่าสนใจว่า มีภาษาโปรแกรมที่เรียกว่า [ฟังก์ชันเชิงบริสุทธิ์](https://en.wikipedia.org/wiki/Purely_functional_programming) เช่น [Haskell](https://en.wikipedia.org/wiki/Haskell) ซึ่งห้ามไม่ให้เปลี่ยนค่าตัวแปรเด็ดขาด -ในภาษาเหล่านี้, เมื่อค่าถูกจัดเก็บ "ในกล่อง" มันจะอยู่ที่นั่นตลอดไป ถ้าเราต้องการจัดเก็บสิ่งอื่น ภาษาจะบังคับให้เราสร้างกล่องใหม่ (ประกาศตัวแปรใหม่) เราไม่สามารถนำกล่องเก่ามาใช้ซ้ำได้ +ในภาษาเหล่านี้ เมื่อเก็บค่าใส่ "กล่อง" ไปแล้ว มันจะอยู่ในนั้นตลอดกาล หากต้องการเก็บข้อมูลอย่างอื่น ภาษาจะบังคับให้เราต้องสร้างกล่องใหม่ (ประกาศตัวแปรใหม่) จะนำกล่องเก่ามาใช้ใหม่ไม่ได้ -แม้ว่ามันอาจจะดูแปลก ๆ ในตอนแรก แต่ภาษาเหล่านี้สามารถพัฒนาอย่างจริงจังได้ ยิ่งไปกว่านั้น ยังมีพื้นที่อื่นๆ เช่น การคำนวณแบบขนาน (parallel computations) ซึ่งข้อจำกัดนี้ให้ประโยชน์บางประการ +ถึงแม้พอแรกอาจฟังดูแปลกๆ แต่ภาษาพวกนี้ก็มีความสามารถในการพัฒนาโปรแกรมจริงจังได้นะ ยิ่งไปกว่านั้น ในบางด้านอย่างการประมวลผลแบบขนาน ข้อจำกัดนี้กลับให้ประโยชน์บางอย่างเสียด้วยซ้ำ ``` -## การตั้งชื่อตัวแปร +## การตั้งชื่อตัวแปร [#variable-naming] -ในการตั้งชื่อตัวแปรใน JavaScript มีข้อจำกัด 2 ข้อ: +ในภาษา JavaScript มีข้อจำกัด 2 ประการในการตั้งชื่อตัวแปร: -1. ชื่อต้องประกอบด้วยตัวอักษร, ตัวเลข, หรือสัญลักษณ์ `$` และ `_` เท่านั้น -2. ตัวอักษรตัวแรกต้องไม่เป็นตัวเลข +1. ชื่อต้องประกอบด้วยตัวอักษร ตัวเลข หรือสัญลักษณ์ `$` และ `_` เท่านั้น +2. ตัวอักษรตัวแรกต้องไม่ใช่ตัวเลข -ตัวอย่างของชื่อที่ถูกต้อง: +ตัวอย่างชื่อที่ใช้ได้: ```js let userName; let test123; ``` -เมื่อชื่อประกอบด้วยหลายคำมักจะใช้ [camelCase](https://en.wikipedia.org/wiki/CamelCase) นั่นคือ: หากมีคำต่อกัน คำแรกที่ขึ้นจะเป็นพิมพ์เล็ก ส่วนคำที่เหลือจะเริ่มต้นด้วยพิมพ์ใหญ่: `myVeryLongName` +เมื่อชื่อประกอบด้วยหลายคำ มักนิยมใช้รูปแบบ [camelCase](https://en.wikipedia.org/wiki/CamelCase) นั่นคือเขียนคำต่อกันเรื่อยๆ โดยขึ้นต้นคำแรกด้วยตัวพิมพ์เล็ก ส่วนคำถัดๆ ไปให้ขึ้นต้นด้วยตัวพิมพ์ใหญ่ เช่น `myVeryLongName` -สิ่งที่น่าสนใจ - สัญลักษณ์ดอลลาร์ `'$'` และขีดล่าง `'_'` สามารถใช้ในชื่อได้ พวกเขาเป็นสัญลักษณ์ปกติเหมือนตัวอักษร ไม่มีความหมายพิเศษ +ที่น่าสนใจคือ เครื่องหมายดอลลาร์ `'$'` และอันเดอร์สกอร์ `'_'` ก็สามารถใช้เป็นส่วนหนึ่งของชื่อได้ โดยมันเป็นแค่สัญลักษณ์ธรรมดาเหมือนตัวอักษร ไม่ได้มีความหมายพิเศษอะไร -เราสามารถตั้งชื่อแบบนี้ได้: +ชื่อเหล่านี้ใช้ได้: ```js run untrusted let $ = 1; // ประกาศตัวแปรชื่อ "$" -let _ = 2; // และตอนนี้ตัวแปรชื่อ "_" +let _ = 2; // และนี่ตัวแปรชื่อ "_" alert($ + _); // 3 ``` -ตัวอย่างชื่อตัวแปรที่ไม่ถูกต้อง: +ตัวอย่างชื่อตัวแปรที่ใช้ไม่ได้: ```js no-beautify -let 1a; // ไม่สามารถเริ่มต้นด้วยตัวเลข +let 1a; // ห้ามขึ้นต้นด้วยตัวเลข -let my-name; // ไม่อนุญาตให้ใช้ขีดกลาง '-' ในชื่อ +let my-name; // เครื่องหมายขีด '-' ไม่อนุญาตให้ใช้ในชื่อ ``` -```smart header="ตัวพิมพ์ใหญ่และตัวพิมพ์เล็กมีความแตกต่าง" -ตัวแปรที่ชื่อ `apple` และ `APPLE` เป็นตัวแปรคนละตัวกัน +```smart header="ตัวพิมพ์ใหญ่-เล็กมีผล" +ตัวแปร `apple` กับ `APPLE` ถือเป็นคนละตัวกัน ``` -````smart header="อนุญาตให้ใช้ตัวอักษรที่ไม่ใช่ละติน แต่ไม่แนะนำ" -เราสามารถใช้ภาษาใดๆ รวมถึงตัวอักษรซีริลลิค ตัวอักษรจีนและอื่น ๆ มาตั้งชื่อตัวแปรได้เช่น: +```smart header="อักษรที่ไม่ใช่ภาษาอังกฤษใช้ได้ แต่ไม่แนะนำ" +เราสามารถใช้ภาษาอื่นๆ ได้ รวมถึงอักษรภาษารัสเซีย อักษรจีน หรืออื่นๆ เช่น: ```js -let ชื่อ = '...'; -let ผม = '...'; +let имя = '...'; +let 我 = '...'; ``` -ทางเทคนิค ไม่มีข้อผิดพลาด ชื่อเหล่านี้อนุญาต แต่มีข้อตกลงระหว่างประเทศที่จะใช้ภาษาอังกฤษในชื่อตัวแปร แม้ว่าเราจะเขียนสคริปต์ขนาดเล็ก มันอาจมีอายุยาวไปข้างหน้า คนจากประเทศอื่นอาจจำเป็นต้องอ่านโค้ดที่เราเขียนขึ้นมาก็ได้ -```` +ในทางเทคนิคแล้ว ตัวอย่างข้างบนไม่มีข้อผิดพลาด การตั้งชื่อแบบนั้นใช้ได้ แต่เรามีข้อตกลงสากลว่าควรใช้ภาษาอังกฤษในการตั้งชื่อตัวแปร เพราะถึงแม้จะเป็นสคริปต์สั้นๆ แต่ก็อาจจะมีชีวิตอยู่ได้นานมาก และในอนาคตอาจมีคนจากประเทศอื่นจำเป็นต้องเข้ามาอ่านมันก็เป็นได้ +``` -````warn header="ชื่อที่ถูกสงวนไว้" -มี[รายชื่อคำที่ถูกสงวนไว้](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords) ที่ไม่สามารถใช้เป็นชื่อตัวแปรได้ เนื่องจากคำเหล่านี้ถูกใช้โดยภาษาเอง +```warn header="ชื่อที่สงวนไว้" +มี[รายการคำสงวน](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords) ที่ไม่อนุญาตให้นำมาตั้งเป็นชื่อตัวแปร เพราะมันถูกสงวนไว้ใช้โดยตัวภาษาเอง -เช่น: `let`, `class`, `return`, และ `function` ถูกสงวนไว้ +ตัวอย่างเช่น: `let`, `class`, `return` และ `function` เป็นคำสงวน -โค้ดด้านล่างนี้จะให้ข้อผิดพลาดทางไวยากรณ์: +โค้ดด้านล่างจะเกิด syntax error: ```js run no-beautify -let let = 5; // ไม่สามารถตั้งชื่อตัวแปรเป็น "let", ข้อผิดพลาด! -let return = 5; // ไม่สามารถตั้งชื่อตัวแปรเป็น "return" ได้, ข้อผิดพลาด! +let let = 5; // ไม่สามารถตั้งชื่อตัวแปรว่า "let" เพราะเป็นคำสงวน เกิด error! +let return = 5; // เช่นเดียวกัน ห้ามตั้งชื่อเป็น "return" เกิด error! +``` ``` -```` -````warn header="การกำหนดค่าโดยไม่มี `use strict`" +```warn header="การกำหนดค่าโดยไม่ใช้ `use strict`" -โดยปกติเราต้องกำหนดตัวแปรก่อนที่จะใช้งาน แต่ในยุคเก่าๆ มันเป็นไปได้ทางเทคนิคที่จะสร้างตัวแปรโดยการกำหนดค่าเพียงอย่างเดียวโดยไม่ใช้ `let` นี่ยังทำงานได้ตอนนี้ถ้าเราไม่ใส่ `use strict` ในสคริปต์ของเราเพื่อรักษาความสามารถในการทำงานร่วมกับสคริปต์เก่า +โดยปกติแล้วเราต้องประกาศตัวแปรก่อนใช้งาน แต่ในสมัยก่อนมีช่องโหว่ทางเทคนิคที่ทำให้สร้างตัวแปรได้โดยแค่กำหนดค่าให้มันเลย โดยไม่ต้องใช้ `let` ซึ่งยังคงใช้ได้อยู่ในปัจจุบันหากไม่ใส่ `use strict` ลงในสคริปต์ เพื่อรักษาความเข้ากันได้กับสคริปต์เก่าๆ ```js run no-strict -// หมายเหตุ: ไม่มี "use strict" ในตัวอย่างนี้ +// หมายเหตุ: ไม่มีการใช้ "use strict" ในตัวอย่างนี้ -num = 5; // ตัวแปร "num" ถูกสร้างขึ้นถ้ายังไม่มีอยู่ +num = 5; // ถ้าไม่มีตัวแปร "num" มันจะถูกสร้างขึ้นโดยอัตโนมัติ alert(num); // 5 ``` -นี่เป็นแนวปฏิบัติที่ไม่ดีและจะทำให้เกิดข้อผิดพลาดในโหมดสมัยใหม่: +วิธีนี้ถือเป็นแนวปฏิบัติที่ไม่ดี และจะเกิดข้อผิดพลาดในโหมดเข้มงวด (strict mode): ```js "use strict"; *!* -num = 5; // ข้อผิดพลาด: num ไม่ได้ถูกกำหนด +num = 5; // error: ตัวแปร num ไม่ได้ถูกประกาศไว้ก่อน */!* -```` +``` -## ค่าคงที่ (constant) +## ค่าคงที่ (Constants) -เพื่อประกาศตัวแปรคงที่ (ไม่เปลี่ยนแปลง), ให้ใช้ `const` แทน `let`: +เพื่อประกาศตัวแปรค่าคงที่ (ไม่เปลี่ยนแปลงค่า) ให้ใช้ `const` แทน `let`: ```js const myBirthday = '18.04.1982'; ``` -ตัวแปรที่ประกาศด้วย `const` เรียกว่า "ค่าคงที่" ไม่สามารถเปลี่ยนแปลงค่าได้ การจะเปลี่ยนแปลงค่าจะทำให้เกิดข้อผิดพลาด: +ตัวแปรที่ประกาศด้วย `const` จะเรียกว่า "ค่าคงที่" ซึ่งไม่สามารถกำหนดค่าใหม่ได้ หากพยายามทำเช่นนั้นจะเกิดข้อผิดพลาด: ```js run const myBirthday = '18.04.1982'; -myBirthday = '01.01.2001'; // ข้อผิดพลาด, ไม่สามารถเปลี่ยนค่าคงที่ได้! +myBirthday = '01.01.2001'; // error เพราะไม่สามารถกำหนดค่าใหม่ให้ค่าคงที่ได้! ``` -เมื่อนักพัฒนาโปรแกรมมั่นใจว่าตัวแปรจะไม่เปลี่ยนแปลง, พวกเขาสามารถประกาศด้วย `const` เพื่อรับรองและสื่อสารอย่างชัดเจนให้ทุกคนทราบ +เมื่อโปรแกรมเมอร์มั่นใจว่าตัวแปรจะไม่มีวันเปลี่ยนแปลงค่า ก็สามารถประกาศเป็นค่าคงที่ด้วย `const` เพื่อการันตีและสื่อสารข้อเท็จจริงดังกล่าวให้ทุกคนรับทราบ -### ค่าคงที่เป็นตัวพิมพ์ใหญ่ +### ค่าคงที่ที่เขียนด้วยตัวพิมพ์ใหญ่ -มีการปฏิบัติที่แพร่หลายในการใช้ค่าคงที่เป็นนามแฝงสำหรับค่าที่ยากต่อการจดจำและที่ไม่ควรเปลี่ยนแปลง (เช่น, ค่าที่ใช้ในการกำหนดสี, ขนาดของรูปภาพ, และอื่นๆ) +ในทางปฏิบัติ มักนิยมใช้ค่าคงที่เป็นนามแทนสำหรับค่าที่จำยาก ซึ่งทราบค่าตายตัวก่อนการประมวลผลโปรแกรมแล้ว -ค่าคงที่เหล่านั้นมีชื่อเป็นตัวพิมพ์ใหญ่และแบ่งคำด้วยเครื่องหมายขีดล่าง `_` +ค่าคงที่ลักษณะนี้มักตั้งชื่อโดยใช้ตัวพิมพ์ใหญ่และอันเดอร์สกอร์ -ตัวอย่างเช่น มาสร้างค่าคงที่สำหรับสีในรูปแบบ "เว็บ" (ฐานสิบหก): +ยกตัวอย่างเช่น ลองสร้างค่าคงที่แทนรหัสสีในฟอร์แมต "web" (เขียนเป็นเลขฐานสิบหก): ```js run const COLOR_RED = "#F00"; @@ -275,70 +278,70 @@ const COLOR_GREEN = "#0F0"; const COLOR_BLUE = "#00F"; const COLOR_ORANGE = "#FF7F00"; -// ...เมื่อเราต้องการเลือกสี +// เมื่อต้องการเลือกสีใดสีหนึ่ง let color = COLOR_ORANGE; alert(color); // #FF7F00 ``` -ประโยชน์: +ข้อดี: -- `COLOR_ORANGE` ง่ายต่อการจำมากกว่า `"#FF7F00"` -- เราพิมพ์เลขฐานสิบหกอย่าง `"#FF7F00"` ผิดได้ง่ายกว่า `COLOR_ORANGE` -- เมื่ออ่านโค้ด `COLOR_ORANGE` เราจะเข้าใจว่าหมายถึงสีอะไรมากกว่า `#FF7F00` +- `COLOR_ORANGE` จำได้ง่ายกว่า `"#FF7F00"` มาก +- พิมพ์ผิดเป็น `"#FF7F00"` ได้ง่ายกว่า `COLOR_ORANGE` +- เวลาอ่านโค้ด `COLOR_ORANGE` สื่อความหมายได้ชัดเจนกว่า `#FF7F00` -เมื่อไหร่เราควรใช้ตัวพิมพ์ใหญ่สำหรับค่าคงที่และเมื่อไหร่เราควรตั้งชื่อแบบปกติ? มาเคลียร์เรื่องนี้ให้ชัดเจน +แล้วเราควรใช้ตัวพิมพ์ใหญ่กับค่าคงที่เมื่อไหร่ และควรตั้งชื่อปกติเมื่อไหร่? ลองมาทำความเข้าใจกัน -การเป็น "ค่าคงที่" หมายความว่าค่าของตัวแปรไม่เปลี่ยนแปลง แต่มีค่าคงที่ที่ทราบก่อนการดำเนินการ (เช่น ค่าสีแดงแบบฐานสิบหก) และมีค่าคงที่ที่ *คำนวณ* ในเวลาทำงาน ระหว่างการดำเนินการ แต่ไม่เปลี่ยนแปลงหลังจากการกำหนดค่าเริ่มต้น +คำว่า "ค่าคงที่" หมายถึงค่าของตัวแปรจะไม่มีวันเปลี่ยนแปลงเท่านั้น แต่ค่าคงที่บางตัวเป็นที่รู้จักก่อนการประมวลผล (เช่นค่าฐานสิบหกของสีแดง) ส่วนค่าคงที่อีกประเภทคือถูก*คำนวณ*ระหว่างรันไทม์ ในช่วงการประมวลผล แต่จะไม่เปลี่ยนแปลงหลังจากกำหนดค่าไปแล้ว ตัวอย่างเช่น: ```js -const pageLoadTime = /* เวลาที่ใช้ในการโหลดหน้าเว็บ */; +const pageLoadTime = /* เวลาที่ใช้ในการโหลดเว็บเพจ */; ``` -ค่าของ `pageLoadTime` ไม่รู้ก่อนโหลดหน้าเว็บ ดังนั้นจึงตั้งชื่อเป็นปกติ แต่มันยังคงเป็นค่าคงที่เพราะมันไม่เปลี่ยนแปลงหลังจากการกำหนดค่า +ค่าของ `pageLoadTime` ไม่เป็นที่ทราบก่อนโหลดเพจ ดังนั้นจึงตั้งชื่อแบบปกติ แต่ถึงอย่างนั้นมันก็ยังเป็นค่าคงที่ เพราะไม่มีการเปลี่ยนแปลงค่าหลังจากกำหนดไปแล้ว -กล่าวอีกนัยหนึ่ง ค่าคงที่ที่มีตัวพิมพ์ใหญ่ถูกใช้เพียงเป็นชื่อย่อสำหรับค่าที่เข้ารหัสแบบ "hard-coded" เท่านั้น +หรือพูดอีกอย่างคือ ค่าคงที่ที่ตั้งชื่อด้วยตัวพิมพ์ใหญ่จะใช้เป็นเพียงแค่นามแทนสำหรับค่าที่ "ฮาร์ดโค้ด" เข้าไปโดยตรงเท่านั้น -## ## เรียกชื่อให้ถูกต้อง +## ตั้งชื่อให้ถูกต้อง -เมื่อพูดถึงตัวแปร ยังมีสิ่งสำคัญอีกอย่างหนึ่งที่สำคัญมากที่สุด +เมื่อพูดถึงตัวแปร มีอีกเรื่องสำคัญมากที่ต้องคำนึงถึง นั่นคือ -ชื่อตัวแปรควรมีความหมายที่ชัดเจนและเป็นที่เข้าใจง่าย และอธิบายถึงข้อมูลที่ตัวแปรเก็บได้ +ชื่อตัวแปรควรมีความหมายที่ชัดเจน เข้าใจง่าย สามารถอธิบายข้อมูลที่เก็บอยู่ภายในได้ -การตั้งชื่อตัวแปรเป็นหนึ่งในทักษะที่สำคัญและซับซ้อนที่สุดในการเขียนโปรแกรม ด้วยการสังเกตชื่อตัวแปรแค่รูปแบบสั้นๆ เราสามารถรู้ว่าโค้ดนั้นเขียนโดยผู้เริ่มต้นหรือนักพัฒนาที่มีประสบการณ์แล้วได้เลย +การตั้งชื่อตัวแปรถือเป็นหนึ่งในทักษะที่สำคัญและซับซ้อนที่สุดในการเขียนโปรแกรม เพียงแค่กวาดตามองผ่านชื่อตัวแปร ก็สามารถบอกได้แล้วว่าโค้ดนั้นเขียนโดยมือใหม่หรือนักพัฒนาที่มีประสบการณ์ -ในโปรเจคจริง ส่วนใหญ่ของเวลาจะใช้ในการปรับแก้และขยายโค้ดที่มีอยู่แล้ว มากกว่าการเขียนโค้ดใหม่จากต้นเริ่มทั้งหมด ดังนั้นเมื่อเรากลับมาดูโค้ดบางส่วนหลังจากทำสิ่งอื่นไปพักหนึ่งครั้ง การหาข้อมูลที่มีการตั้งชื่อได้ดีจะง่ายกว่ามาก กล่าวอีกนัยหนึ่งคือเมื่อตัวแปรมีชื่อที่ดี +ในโปรเจ็กต์จริง เรามักใช้เวลาส่วนใหญ่ไปกับการแก้ไขและต่อยอดโค้ดเดิมที่มีอยู่แล้ว มากกว่าการเขียนโค้ดใหม่ล้วนๆ จากศูนย์ เมื่อต้องย้อนกลับไปดูโค้ดหลังจากไปทำอย่างอื่นสักพัก การมีข้อมูลที่ตั้งชื่อตัวแปรไว้อย่างดีจะช่วยให้เราหาสิ่งที่ต้องการได้ง่ายขึ้นมาก หรือพูดอีกอย่างคือ เมื่อตัวแปรมีชื่อที่ดีนั่นเอง -กรุณาใช้เวลาในการคิดชื่อที่ถูกต้องสำหรับตัวแปรก่อนที่จะประกาศ การทำเช่นนี้จะช่วยให้คุณประหยัดเวลาในการเขียนโค้ดในอนาคต +ดังนั้น ควรใช้เวลาคิดพิจารณาชื่อที่เหมาะสมให้ตัวแปร ก่อนที่จะประกาศใช้มัน การทำเช่นนี้จะคุ้มค่าเป็นอย่างมากในภายหลัง -กฎที่ควรจำไว้บางอย่างคือ: +ต่อไปนี้คือกฎที่ควรนำไปปฏิบัติ: -- ใช้ชื่อที่อ่านง่ายเหมือน `userName` หรือ `shoppingCart` -- หลีกเลี่ยงการใช้ตัวย่อหรือชื่อสั้นเช่น `a`, `b`, `c` ยกเว้นในกรณีที่เราแน่ใจว่าเราทำอะไรอยู่จริงๆ -- ตั้งชื่อให้เป็นอย่างสั้นและอธิบายได้มากที่สุด ตัวอย่างของชื่อที่ไม่ดีคือ `data` และ `value` เช่นนั้นชื่อเหล่านี้ไม่พูดอะไรเลย แต่ถ้ามีข้อความในโค้ดที่ชัดเจนว่าตัวแปรนั้นอ้างถึงข้อมูลหรือค่าใด ๆ ก็ยอมใช้ชื่อเหล่านี้ได้ -- ตกลงเรื่องของคำศัพท์ภายในทีมและในใจของคุณเอง หากผู้เยี่ยมชมเว็บไซต์เรียกว่า "ผู้ใช้" แล้วเราควรตั้งชื่อตัวแปรที่เกี่ยวข้องว่า `currentUser` หรือ `newUser` แทนที่จะเป็น `currentVisitor` หรือ `newManInTown` +- ใช้ชื่อที่มนุษย์อ่านเข้าใจได้ เช่น `userName` หรือ `shoppingCart` +- หลีกเลี่ยงการใช้คำย่อหรือชื่อสั้นๆ อย่าง `a`, `b` หรือ `c` ยกเว้นว่าคุณมั่นใจว่ากำลังทำอะไรอยู่ +- ตั้งชื่อให้อธิบายได้ชัดเจนที่สุดและกระชับ ตัวอย่างชื่อที่ไม่ดี ได้แก่ `data` และ `value` เพราะไม่ได้สื่อความหมายอะไร ยกเว้นบริบทของโค้ดจะบ่งชี้ชัดว่าตัวแปรนั้นหมายถึงข้อมูลหรือค่าใด +- ตกลงใช้ศัพท์เฉพาะกันภายในทีมและในใจของคุณเอง ถ้าเรียกผู้เยี่ยมชมเว็บว่า "user" เราก็ควรตั้งชื่อตัวแปรที่เกี่ยวข้องว่า `currentUser` หรือ `newUser` แทนที่จะเป็น `currentVisitor` หรือ `newManInTown` -ง่ายหรือเปล่า? ใช่ในความเป็นจริง แต่การสร้างชื่อตัวแปรที่อธิบายได้ละเอียดและกระชับในการปฏิบัติจริงนั้นไม่ง่ายนัก +ฟังดูง่ายมั้ย แต่ในทางปฏิบัติ การสร้างชื่อตัวแปรที่สื่อความหมายและกระชับไม่ใช่เรื่องง่ายเลย ลองทำดูนะ -```smart header="Reuse or create?" -และข้อคิดสุดท้าย มีนักพัฒนาโปรแกรมบางคนที่ขี้เกียจที่จะประกาศตัวแปรใหม่และมักจะนำตัวแปรที่มีอยู่มาใช้ซ้ำ +```smart header="ใช้ซ้ำหรือสร้างใหม่" +และอีกหนึ่งข้อสังเกต มีนักเขียนโปรแกรมบางส่วนที่ขี้เกียจ ชอบเอาตัวแปรที่มีอยู่แล้วมาใช้ซ้ำ แทนที่จะประกาศตัวแปรใหม่ -ผลที่ได้คือตัวแปรของพวกเขากลายเป็นกล่องที่คนอื่นๆ หยอดสิ่งต่างๆ เข้าไปโดยไม่เปลี่ยนสติกเกอร์ สิ่งใดอยู่ข้างในกล่องตอนนี้? ไม่มีใครรู้? เราต้องเปิดกล่องเพื่อดู +ผลที่ได้ก็คือ ตัวแปรของพวกเขาจะเหมือนกล่องที่มีคนเอาของต่างๆ ใส่ลงไป โดยไม่เปลี่ยนป้ายข้างนอก แล้วตอนนี้ในกล่องมีอะไรบ้าง? ไม่มีใครรู้ ต้องเดินเข้าไปดูใกล้ๆ -นักพัฒนาเช่นนี้ประหยัดเล็กน้อยในการประกาศตัวแปร แต่สูญเสียมากกว่าสิบเท่านั้นในการแก้บั๊ก +โปรแกรมเมอร์พวกนี้อาจจะประหยัดการประกาศตัวแปรไปได้นิดหน่อย แต่กลับเสียเวลาดีบั๊กไปมากกว่าสิบเท่า -ตัวแปรเพิ่มขึ้นเป็นสิ่งที่ดี ไม่ใช่สิ่งที่แย่ มันช่วยให้โค้ดของคุณอ่านง่ายขึ้น และช่วยให้คุณเข้าใจโค้ดของคุณได้ดีขึ้น +การมีตัวแปรเพิ่มถือว่าดี ไม่ใช่เรื่องไม่ดี -เครื่องมือสกัดรหัส (minifiers) JavaScript และเบราว์เซอร์รุ่นใหม่สามารถปรับปรุงโค้ดได้ดีเพียงพอ ดังนั้นมันจะไม่สร้างปัญหาเรื่องประสิทธิภาพ การใช้ตัวแปรที่แตกต่างกันสำหรับค่าที่แตกต่างกันอาจช่วยให้เครื่องมือ (engine) ปรับปรุงรหัสของเราได้ดียิ่งขึ้น +JavaScript minifier และเบราว์เซอร์สมัยใหม่ สามารถปรับแต่งโค้ดได้ดีพอที่จะไม่ก่อให้เกิดปัญหาด้านประสิทธิภาพ และการใช้ตัวแปรต่างกันเพื่อเก็บค่าที่ต่างกัน ยังช่วยให้เอนจินสามารถปรับแต่งโค้ดให้ดีขึ้นได้อีกด้วย ``` ## สรุป -เราสามารถประกาศตัวแปรเพื่อเก็บข้อมูลได้โดยใช้คีย์เวิร์ค `var`, `let`, หรือ `const` +เราสามารถประกาศตัวแปรเพื่อเก็บข้อมูลโดยใช้คีย์เวิร์ด `var`, `let` หรือ `const` -- `let` -- เป็นการประกาศตัวแปรในแบบสมัยใหม่ -- `var` -- เป็นการประกาศตัวแปรแบบสมัยเก่า โดยทั่วไปเราจะไม่ได้ใช้มันเลย แต่เราจะพูดถึงความแตกต่างที่ละเอียดเรื่อง `var` ในบทที่ ไว้กรณีที่คุณต้องการใช้มัน -- `const` -- เป็นเหมือน `let` แต่ค่าของตัวแปรไม่สามารถเปลี่ยนแปลงได้ +- `let` -- เป็นรูปแบบการประกาศตัวแปรแบบสมัยใหม่ +- `var` -- เป็นการประกาศตัวแปรแบบเก่า ปกติเราไม่ค่อยใช้แล้ว แต่เราจะกล่าวถึงความแตกต่างเล็กๆ น้อยๆ จาก `let` ในบทเรียน ในกรณีที่คุณจำเป็นต้องใช้มัน +- `const` -- คล้ายกับ `let` แต่ค่าของตัวแปรจะไม่สามารถเปลี่ยนแปลงได้ -ตัวแปรควรตั้งชื่อให้เข้าใจง่ายเพื่อสื่อว่าข้อมูลภายในมีอะไรอยู่ และควรเป็นคำที่สั้นๆ และอ่านง่าย \ No newline at end of file +ตัวแปรควรถูกตั้งชื่อในลักษณะที่ทำให้เราสามารถเข้าใจได้โดยง่าย ว่ามีข้อมูลอะไรถูกเก็บอยู่ภายใน