diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md index d5c262380..3a8bf0b66 100644 --- a/1-js/02-first-steps/18-javascript-specials/article.md +++ b/1-js/02-first-steps/18-javascript-specials/article.md @@ -1,23 +1,23 @@ -# จาวาสคริปต์พิเศษ +# ความพิเศษของ JavaScript -ในบทนี้เราจะสรุปฟีเจอร์ของจาวาสคริปต์ ที่เราเรียนรู้กันไปจากบทที่ผ่านๆมาแบบสั้นๆ แต่จะใส่ใจรายละเอียดเล็กๆน้อยๆเป็นพิเศษ +บทนี้จะสรุปย่อคุณลักษณะของ JavaScript ที่เราได้เรียนมาจนถึงตอนนี้ โดยให้ความสนใจเป็นพิเศษกับจุดละเอียดอ่อน -## โค้ดสร้างภาษา +## โครงสร้างโค้ด -คำสั่ง (Statements) แต่ละคำสั่งคั่นด้วย semicolon (;) เสมอ +คำสั่งจะถูกคั่นด้วยเครื่องหมายอัฒภาค (semicolon): ```js run no-beautify alert('Hello'); alert('World'); ``` -และการเว้นละบรรทัดก็ถือว่าเป็นการคั่นคำสั่งอย่างหนึ่ง เราสามารถใช้ได้เช่นกัน +โดยทั่วไปแล้ว การขึ้นบรรทัดใหม่ก็ถือเป็นตัวคั่นเช่นกัน ดังนั้นแบบนี้ก็ใช้ได้เช่นกัน: ```js run no-beautify alert('Hello') alert('World') ``` -โดยจาวาสคริปต์จะทำการใส่ semicolon (;) ให้เองโดยอัตโนมัติ แต่บางครั้งเราก็ไม่สามารถเว้นบรรทัดแบบนี้ได้ เช่น +เรียกว่า "การแทรกเครื่องหมายอัฒภาคอัตโนมัติ" แต่บางครั้งก็ไม่ทำงาน ยกตัวอย่างเช่น: ```js run alert("There will be an error after this message") @@ -25,27 +25,27 @@ alert("There will be an error after this message") [1, 2].forEach(alert) ``` -ดังนั้นคู่มือจาวาสคริปต์ส่วนใหญ่จึงแนะนำให้ใส่ semicolon (;) คั่นคำสั่งทุกครั้ง +คู่มือรูปแบบการเขียนโค้ดส่วนใหญ่เห็นพ้องกันว่า เราควรใส่เครื่องหมายอัฒภาคหลังแต่ละคำสั่ง -เราไม่จำเป็นต้องใส่ semicolon (;) ข้างหลัง code block `{...}` หรือรูปประโยคแบบ `for...loop`: +ไม่จำเป็นต้องใช้เครื่องหมายอัฒภาคหลังบล็อกโค้ด `{...}` และโครงสร้างทางไวยากรณ์ที่มีบล็อกเหล่านั้น เช่น ลูป: ```js function f() { - // ไม่จำเป็นต้องใส่ semicolon (;) หลังจากการประกาศฟังก์ชัน + // ไม่ต้องใส่เครื่องหมายอัฒภาคหลังการประกาศฟังก์ชัน } for(;;) { - // ไม่จำเป็นต้องใส่ semicolon (;) หลังลูบ + // ไม่ต้องใส่เครื่องหมายอัฒภาคหลังลูป } ``` -...แต่ถ้าเราเผลอไปใส่ ก็จะไม่มีข้อผิดพลาด และsemicolon (;) จะถูกละเลยไป จาวาสคริปต์ก็ยังทำงานของมันได้ +...แต่แม้ว่าเราจะใส่เครื่องหมายอัฒภาค "เพิ่มเติม" ไว้ที่ใดสักแห่ง ก็ไม่ถือเป็นข้อผิดพลาด มันจะถูกละเว้น -อ่านเพิ่มเติมได้ในบท: . +อ่านเพิ่มเติมได้ที่: -## Strict mode +## โหมดเข้มงวด (Strict mode) -เพื่อเปิดใช้งานฟีเจอร์ทั้งหมดของจาวาสคริปจ์สมัยใหม่อย่างสมบูรณ์ เราควรเริ่มสคริปต์ด้วย `"use strict"` +เพื่อเปิดใช้งานคุณลักษณะทั้งหมดของ JavaScript สมัยใหม่อย่างเต็มที่ เราควรเริ่มต้นสคริปต์ด้วย `"use strict"` ```js 'use strict'; @@ -53,66 +53,66 @@ for(;;) { ... ``` -คำสั่งต้องอยู่ที่ด้านบนสุดของสคริปต์หรือด้านบนสุดของฟังก์ชัน +คำสั่งนี้จะต้องอยู่ที่ด้านบนสุดของสคริปต์ หรือที่จุดเริ่มต้นของ function body -หากไม่ใส่ `"use strict"` โปรแกรมก็ยังคงทำงานได้ แต่เราจะใช้ได้แต่ฟีเจอร์เก่าๆ +หากไม่มี `"use strict"` ทุกอย่างก็ยังคงทำงานได้ แต่คุณลักษณะบางอย่างจะทำงานในแบบเก่าๆ "แบบเข้ากันได้" โดยทั่วไปเรามักจะต้องการพฤติกรรมแบบสมัยใหม่มากกว่า -ฟีเจอร์ใหม่ๆ (อย่างเช่น class เราจะเขียนไปในบทถัดไป) จะเปิดใช้งานเฉพาะ Strict mode เท่สนั้น +คุณลักษณะสมัยใหม่บางอย่างของภาษา (เช่น คลาส ซึ่งเราจะศึกษาในอนาคต) จะเปิดใช้งานโหมดเข้มงวดโดยอัตโนมัติ -ดูเพิ่มเติมได้ที่: . +อ่านเพิ่มเติมได้ที่: -## ตัวแปร (Variables) +## ตัวแปร -สามารถประกาศได้โดยใช้: +สามารถประกาศตัวแปรได้โดยใช้: - `let` -- `const` (constant, can't be changed) -- `var` (old-style, will see later) +- `const` (ค่าคงที่ ไม่สามารถเปลี่ยนแปลงได้) +- `var` (แบบเก่า จะได้เห็นในภายหลัง) -ชื่อตัวแปรสามารถมี: -- ตัวอักษรและตัวเลข แต่ตัวอักษรตัวแรกต้องไม่เป็นตัวเลข -- สามารถใช้อักขระพิเศษอย่าง `$` และ `_` ได้เทียบเท่ากับตัวอักษร. -- อนุญาตให้ใช้ตัวอักษรที่ไม่ใช่ละตินรวมถึงอักษรอียิปต์โบราณ แต่ไม่เป็นที่นิยม +ชื่อตัวแปรสามารถประกอบด้วย: +- ตัวอักษรและตัวเลข แต่ตัวแรกจะต้องไม่ใช่ตัวเลข +- อักขระ `$` และ `_` เป็นอักขระปกติ เทียบเท่ากับตัวอักษร +- ตัวอักษรที่ไม่ใช่ละตินและอักษรอียิปต์โบราณก็สามารถใช้ได้ แต่ไม่ค่อยนิยมใช้ -ตัวแปรสามารถเก็บข้อมูลอะไรก็ได้ หรือ ข้อมูลชนิดใดๆก็ได้ +ตัวแปรมีการกำหนดชนิดข้อมูลแบบไดนามิก สามารถเก็บค่าใดๆ ก็ได้: ```js let x = 5; x = "John"; ``` -มีข้อมูลทั้งหมด 8 ชนิด: +มีชนิดข้อมูลทั้งหมด 8 ชนิด: -- `number` สำหรับทั้งเลขทศนิยมและจำนวนเต็ม -- `bigint` สำหรับจำนวนเต็มหรือตัวเลขที่มีค่าเกิน `2^53 - 1` -- `string` สำหรับสตริง -- `boolean` สำหรับค่าทางตรรกะ: `true/false`, -- `null` -- ชนิดที่มีค่าเดียวคือ `null` หมายถึง "ค่าว่าง" หรือ "ค่านั้นไม่มีอยู่" -- `undefined` -- ชนิดที่มีค่าเดียวคือ `undefined` หมายถึง "ยังไม่ถูกกำหนดค่า", -- `object` และ `symbol` -- สำหรับโครงสร้างข้อมูลที่ซับซ้อนและ unique identifiers ซึ่งเราจะได้เรียนกันในบทถัดๆไป +- `number` สำหรับตัวเลขทั้งจำนวนจริงและจำนวนเต็ม +- `bigint` สำหรับจำนวนเต็มที่มีความยาวตามต้องการ +- `string` สำหรับข้อความ +- `boolean` สำหรับค่าตรรกะ: `true/false` +- `null` -- ชนิดข้อมูลที่มีค่าเดียวคือ `null` หมายถึง "ว่างเปล่า" หรือ "ไม่มีอยู่" +- `undefined` -- ชนิดข้อมูลที่มีค่าเดียวคือ `undefined` หมายถึง "ยังไม่ได้กำหนดค่า" +- `object` และ `symbol` -- สำหรับโครงสร้างข้อมูลที่ซับซ้อน และตัวระบุที่ไม่ซ้ำกัน เรายังไม่ได้เรียนรู้เกี่ยวกับสิ่งเหล่านี้ -ตัวดำเนินการ `typeof` ส่งคืนประเภทของค่า โดยมีข้อยกเว้นสองประการ: +ตัวดำเนินการ `typeof` จะคืนค่าชนิดข้อมูลของค่านั้นๆ โดยมีข้อยกเว้นสองกรณี: ```js -typeof null == "object" // ได้ true เป็นบัคของภาษา -typeof function(){} == "function" // ได้ function +typeof null == "object" // ข้อผิดพลาดในภาษา +typeof function(){} == "function" // ฟังก์ชันจะถูกจัดการเป็นพิเศษ ``` -อ่านเพิ่มเติมได้ในบท: และ +อ่านเพิ่มเติมได้ที่: และ -## ปฏิสัมพันธ์ (Interaction) +## การโต้ตอบ -การปฎิสัมพันธ์เกิดขึ้นบนเบราเซอร์ มีฟังก์ชันพื้นฐานดังนี้: +เนื่องจากเรากำลังใช้เบราว์เซอร์เป็นสภาพแวดล้อมในการทำงาน ฟังก์ชัน UI พื้นฐานจึงประกอบด้วย: -[`prompt(question, [default])`](mdn:api/Window/prompt) -: ถามคำถาม `question` และส่งคืนสิ่งที่ผู้ใช้ป้อนหรือส่ง `null` หากผู้ใช้กด "cancel" +[`prompt(question, [default])`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) +: ถาม `question` และคืนค่าสิ่งที่ผู้ใช้ป้อนเข้ามา หรือ `null` หากผู้ใช้คลิก "ยกเลิก" -[`confirm(question)`](mdn:api/Window/confirm) -: ถามคำถาม `question` ให้ผู้ใช้เลือกระหว่าง Ok หรือ Cancel หากกด Ok จะส่ง `true` กลับ หากกด Cancel จะส่ง `false` +[`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) +: ถาม `question` และแนะนำให้เลือกระหว่าง ตกลง และ ยกเลิก ทางเลือกจะถูกส่งคืนเป็น `true/false` -[`alert(message)`](mdn:api/Window/alert) -: แสดง `message` +[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert) +: แสดงผล `message` -ฟังก์ชั่นเหล่านี้จะเปิด *modal* ซึ่งจะหยุดการทำงานโค้ดและไม่ให้ผู้ใช้ตอบโต้กับหน้าเว็บชั่วคราว จนกว่าผู้ใช้จะตอบคำถามผ่าน *modal* +ฟังก์ชันเหล่านี้ทั้งหมดเป็นแบบ *modal* หมายความว่าจะหยุดการทำงานของโค้ด และป้องกันไม่ให้ผู้ใช้โต้ตอบกับหน้าเว็บจนกว่าจะตอบคำถาม ตัวอย่างเช่น: @@ -124,61 +124,61 @@ alert( "Visitor: " + userName ); // Alice alert( "Tea wanted: " + isTeaWanted ); // true ``` -อ่านเพิ่มเติมในบท: . +อ่านเพิ่มเติมได้ที่: ## ตัวดำเนินการ (Operators) -จาวาสคริปต์มีตัวดำเนินการดังนี้: +JavaScript รองรับตัวดำเนินการดังต่อไปนี้: -ตัวดำเนินการทางคณิตศาสคร์ -: ได้แก่ `* + - /` รวมถึง `%` สำหรับหาเศษเหลือจากการหาร `**` สำหรับการยกกำลัง +ทางคณิตศาสตร์ +: ปกติ: `* + - /` รวมถึง `%` สำหรับการหารเอาเศษ และ `**` สำหรับการยกกำลัง - การใช้ `+` รวมสตริงสองตัวไว้ด้วยกัน และหากตัวถูกดำเนินการหนึ่งตัวเป็นสตริง ไม่ว่าจะอีกตัวจะเป็นข้อมูลชนิดใดจะถูกแปลงให้เป็นสตริงด้วย + ตัวดำเนินการบวก `+` แบบสองตัวถูกกระทำจะเชื่อมต่อสตริง และถ้าตัวใดตัวหนึ่งเป็นสตริง อีกตัวก็จะถูกแปลงเป็นสตริงด้วยเช่นกัน: ```js run - alert( '1' + 2 ); // '12' เป็นสตริง - alert( 1 + '2' ); // '12' เป็นสตริง + alert( '1' + 2 ); // '12', string + alert( 1 + '2' ); // '12', string ``` การกำหนดค่า -: รูปประโยคการกำหนดค่ามีหน้าตาแบบนี้ `a = b` หรือจะใช้คู่กับตัวดำเนินการทางคณิตศาสคร์ก็ได้อย่าง `a *= 2` +: มีการกำหนดค่าธรรมดา: `a = b` และแบบรวมต่างๆ เช่น `a *= 2` -การแปลงเป็นไบนารี -: ตัวดำเนินการแปลงเป็นไบนารีทำงานกับจำนวนเต็ม 32 บิตที่ระดับบิตต่ำสุด: โปรดดู [เอกสาร](mdn:/JavaScript/Guide/Expressions_and_Operators#Bitwise) เมื่อต้องใช้การแปลงเป็นไบนารี +การดำเนินการระดับบิต +: ตัวดำเนินการระดับบิตจะทำงานกับจำนวนเต็ม 32 บิตที่ระดับบิตต่ำสุด: ดูที่ [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) เมื่อต้องการ -เงื่อนไข -: ตัวดำเนินการเดียวที่ใช้สามพารามิเตอร์: `cond ? resultA : resultB` หาก `cond` เป็นจริงจะส่ง `resultA` กลับ หากไม่จะส่ง `resultB` กลับ +แบบมีเงื่อนไข +: ตัวดำเนินการเพียงตัวเดียวที่มีสามพารามิเตอร์: `cond ? resultA : resultB` ถ้า `cond` เป็น truthy จะคืนค่า `resultA` ไม่เช่นนั้นจะคืน `resultB` ตัวดำเนินการทางตรรกะ -: ตัว AND `&&` และ OR `||` จะใช้การประเมินผลแบบสั้น (Short-circuit evaluation) ส่งค่ากลับทันทีที่ค่าเป็นไปตามเกณฑ์ (ไม่จำเป็นว่าต้องเป็น `true`/`false`) ตัว NOT `!` จะแปลงค่าที่ถูกดำเนินการเป็นบูลีน จากนั่นจะส่งค่าที่กลับข้ามกลับไป +: AND ตรรกะ `&&` และ OR ตรรกะ `||` จะทำการประเมินแบบลัดวงจรและคืนค่าที่มันหยุด (ไม่จำเป็นต้องเป็น `true/false`) NOT ตรรกะ `!` แปลงตัวถูกกระทำเป็น boolean และคืนค่าตรงข้าม -ตัวดำเนินการรวมเป็นโมฆะ (Nullish coalescing operator) -: ตัวดำเนินการ `??` จัดเตรียมวิธีการเลือกค่าที่กำหนดจากรายการตัวแปร ผลลัพธ์ของ `a ?? b` คือ `a` เว้นแต่จะเป็น `null/undefined` ตามด้วย `b` +ตัวดำเนินการ Nullish coalescing +: ตัวดำเนินการ `??` ให้วิธีเลือกค่าที่ถูกกำหนดจากรายการตัวแปร ผลลัพธ์ของ `a ?? b` คือ `a` เว้นแต่มันจะเป็น `null/undefined` จึงจะเป็น `b` การเปรียบเทียบ -: การเปรียบเทียบจะใช้ `==` สำหรับค่าที่แตกต่างกัน จะแปลงค่าท้ังสองเป็นตัวเลข (ยกเว้น `null` และ `undefined` ที่ทั้งค่านี้จะเท่ากัน แต่จะไม่เท่ากับค่าชนิดอื่นๆ) +: การตรวจสอบความเท่ากัน `==` สำหรับค่าที่มีชนิดต่างกันจะแปลงเป็นตัวเลข (ยกเว้น `null` และ `undefined` ซึ่งเท่ากันและไม่เท่ากับอะไรอื่น) ดังนั้นพวกนี้จึงเท่ากัน: ```js run alert( 0 == false ); // true alert( 0 == '' ); // true ``` - การเปรียบเทียบจะแปลงค่าจะแปลงค่าท้ังสองเป็นตัวเลข + การเปรียบเทียบอื่นๆ ก็จะแปลงเป็นตัวเลขด้วยเช่นกัน - ตัวดำเนินการเปรียบเทียบอีกตัวอย่าง `===` จะไม่แปลงค่าทั้งสองเป็นตัวเลข: หากค่าทั้งสองมีชนิดแตกต่างกัน จะถือว่าไม่เท่ากันในทันที + ตัวดำเนินการเปรียบเทียบความเท่ากันแบบเข้มงวด `===` จะไม่แปลงค่า: ชนิดที่ต่างกันเสมอไปจะถือว่าค่าไม่เท่ากัน - ค่า `null` และ `undefined` เป็นค่าพิเศษ: ซึ่งหากเราเปรียบเทียบด้วย `==` ทั้งสองจะเท่ากัน แต่จะไม่เท่ากับค่าชนิดอื่นๆ + ค่า `null` และ `undefined` เป็นพิเศษ: พวกมันเท่ากับ `==` กันเองและไม่เท่ากับอะไรอื่น - การเปรียบเทียบมากน้อย เมื่อนำไปใช้กับสตริง มันจะค่อยๆจับเท่ากันไปทีละตัวอักษร ส่วนค่าชนิดอื่นๆที่ไม่ใช่สตริงจะถูกแปลงเป็นตัวเลข + การเปรียบเทียบมากกว่า/น้อยกว่าจะเปรียบเทียบสตริงทีละอักขระ ส่วนชนิดอื่นจะแปลงเป็นตัวเลข ตัวดำเนินการอื่นๆ -: มีอีกสองสามอย่าง เช่น ตัวดำเนินการจุลภาค +: มีอีกไม่กี่ตัว เช่น comma operator -สามารถดูเพิ่มเติมได้ใน: , , , . +อ่านเพิ่มเติมได้ที่: , , , ## ลูป -- เราได้พูดถึงลูป 3 ประเภท: +- เราได้ครอบคลุมลูป 3 ประเภท: ```js // 1 @@ -197,16 +197,16 @@ alert( "Tea wanted: " + isTeaWanted ); // true } ``` -- ตัวแปรที่ประกาศในลูป `for(let...)` จะมองเห็นได้เฉพาะในลูปเท่านั้น แต่เรายังสามารถละเว้น `let` และใช้ตัวแปรที่มีอยู่ซ้ำได้ -- คำสั่ง `break/continue` สำหรับ `break` คือการหยุดการทำงานของลูปทันที และสำหรับ `continue` คือสั่งให้ลูบเดิมทำงานอีกคร้ัง เราใช้ labels เพื่อหยุดลูบที่ซ้อนกัน +- ตัวแปรที่ประกาศในลูป `for(let...)` จะมองเห็นได้เฉพาะภายในลูปเท่านั้น แต่เราสามารถละเว้น `let` และนำตัวแปรที่มีอยู่แล้วมาใช้ซ้ำได้ +- คำสั่ง `break/continue` ช่วยให้ออกจากลูปทั้งหมด/ออกจากรอบปัจจุบัน ใช้ label เพื่อออกจากลูปที่ซ้อนกันได้ -ดูรายละเอียดเพิ่มเติมได้ใน: . +รายละเอียดใน: -โดยหลังจากบทนี้เราจะไปดูลูบที่จัดการกับ `object` +ในภายหลังเราจะศึกษาลูปชนิดอื่นๆ เพิ่มเติมเพื่อจัดการกับออบเจ็กต์ -## คำสั่ง "switch" +## โครงสร้าง "switch" -คำสั่ง "switch" สามารถใช้แทนที่ `if...else` ได้ คำสั่ง "switch" จะใช้ `===` สำหรับการเปรียบเทียบ +โครงสร้าง "switch" สามารถใช้แทนการตรวจสอบ `if` หลายครั้งได้ มันใช้ `===` (ตรวจสอบความเท่ากันแบบเข้มงวด) ในการเปรียบเทียบ ตัวอย่างเช่น: @@ -215,7 +215,7 @@ let age = prompt('Your age?', 18); switch (age) { case 18: - alert("Won't work"); // ผลลัพธ์ของ prompt เป็นสตริง ไม่ใช่ตัวเลข + alert("Won't work"); // ผลลัพธ์จาก prompt เป็นสตริง ไม่ใช่ตัวเลข break; case "18": @@ -227,13 +227,13 @@ switch (age) { } ``` -สามารถดูรายละเอียดเพิ่มเติมได้ที่: +รายละเอียดใน: ## ฟังก์ชัน -เราได้กล่าวถึงสามวิธีในการสร้างฟังก์ชันในจาวาสคริปต์: +เราได้ครอบคลุมวิธีการสร้างฟังก์ชันใน JavaScript สามแบบ: -1. การประกาศฟังก์ชัน (Function Declaration) +1. Function Declaration: ฟังก์ชันในลำดับการทำงานหลักของโค้ด ```js function sum(a, b) { @@ -243,7 +243,7 @@ switch (age) { } ``` -2. นิพจน์ฟังก์ชัน (Function Expression) +2. Function Expression: ฟังก์ชันในบริบทของนิพจน์ ```js let sum = function(a, b) { @@ -256,29 +256,28 @@ switch (age) { 3. Arrow functions: ```js - // นิพจน์อยู่ทางด้านขวา + // นิพจน์ทางด้านขวา let sum = (a, b) => a + b; - // หรือแบบ code block { ... } แต่อย่าลืมใส่ return ด้วย ไม่งั้นจะได้ undifined กลับไปแทน + // หรือใช้ไวยากรณ์แบบหลายบรรทัดด้วย { ... }, ต้องใส่ return ที่นี่: let sum = (a, b) => { // ... return a + b; } - // แบบไม่มีอาร์กิวเม้นต์ + // ไม่มีอาร์กิวเมนต์ let sayHi = () => alert("Hello"); - // แบบอาร์กิวเม้นต์หนึ่งตัว + // มีอาร์กิวเมนต์เดียว let double = n => n * 2; ``` +- ฟังก์ชันอาจมีตัวแปรภายใน (local variables): คือตัวแปรที่ประกาศภายในบอดี้หรือในรายการพารามิเตอร์ของมัน ตัวแปรเหล่านี้จะมองเห็นได้เฉพาะภายในฟังก์ชัน +- พารามิเตอร์สามารถกำหนดค่าเริ่มต้นได้: `function sum(a = 1, b = 2) {...}` +- ฟังก์ชันจะคืนค่าอะไรบางอย่างเสมอ หากไม่มีประโยค `return` ผลลัพธ์จะเป็น `undefined` -- ฟังก์ชันที่มีตัวแปรภายใน ตัวแปรที่ประกาศภายในฟังก์ชัน จะสามารถมองเห็นได้เฉพาะภายในฟังก์ชันเท่านั้น -- พารามิเตอร์สามารถใส่ค่าตั้งต้นลงไปได้แบบนี้: `function sum(a = 1, b = 2) {...}`. -- ฟังก์ชันจะส่งค่าใดๆกลับเสมอ หากไม่ใส่ `return` ที่บรรทัดสุดท้ายของฟังก์ชัน ฟังก์ชันจะส่ง `undefined` กลับไป +รายละเอียด: ดูที่ , -รายละเอียดเพิ่มเติม: สามารถดูได้ , . +## ในอนาคตยังมีอีกมาก -## อื่นๆกำลังจะตามมา - -ทั้งหมดนี่เป็นการสรุปแบบย่อๆของจาวาสคริปต์ ในตอนนี้เราเรียนไปแค่พื้นฐานเท่านั้น ในบทต่อๆไปเราจะมาเรียนฟีเจอร์ขั้นสูงของจาวาสคริปต์เพิ่มเติม +นี่เป็นเพียงรายการโดยย่อของคุณลักษณะต่างๆ ของ JavaScript ณ ตอนนี้เราได้ศึกษาเฉพาะพื้นฐานเท่านั้น ในบทเรียนต่อๆ ไปคุณจะได้เจอกับคุณสมบัติพิเศษและขั้นสูงของ JavaScript เพิ่มเติม \ No newline at end of file