16 JavaScript Features ยุคใหม่ที่ช่วยให้เขียน Code ปลอดภัยและอ่านง่ายขึ้น
13-พ.ค.-26
คัมภีร์เทพ IT
JavaScript ในปัจจุบันไม่ได้เปลี่ยนแปลงแบบหวือหวาเหมือนยุค ES6 อีกต่อไป แต่กำลังค่อย ๆ พัฒนาไปในทิศทางที่ช่วยให้เขียน Code ที่อ่านง่าย และปลอดภัยมากขึ้นกว่าเดิม บทความนี้จะพาไปรู้จักกับ 16 JavaScript Features ที่ยุคใหม่ที่ช่วยให้เขียน Code ปลอดภัยและอ่านง่ายขึ้น ซึ่ง Dev หลายคนอาจยังไม่เคยใช้ แต่สามารถช่วยยกระดับคุณภาพของ Code ได้อย่างชัดเจนในการทำงานจริง
ES2022 — จุดเริ่มต้นของ JavaScript ยุคใหม่
1. Error.cause
คงมีหลายครั้ง ที่คุณพบว่า Error หนึ่งดันไปเป็นต้นเหตุทำให้เกิดอีก Error หนึ่ง และสุดท้ายบริบทของต้นตอจริง ๆ กลับหายไประหว่างทาง
ก่อนหน้านี้ เรามักเลือกอย่างใดอย่างหนึ่งระหว่าง เขียนทับ Error เดิม หรือใส่ Properties เพิ่มเข้าไปเองแบบ Manual ซึ่งที่จริงก็ไม่ได้ดีนัก
ตอนนี้สามารถใช้:
เราสามารถเชื่อมโยง Error ต้นทางเข้าไปได้โดยตรง
ตัวอย่าง:
ทำให้ Chain ของ Error จะถูกเก็บไว้ครบทั้งหมด
2. Object.hasOwn()
เมื่อก่อน ถ้าเราต้องการตรวจสอบว่า Object หนึ่งมี Property เหล่านี้จริง ๆ หรือไม่
เรามักเขียนแบบนี้:
ถ้าถามว่า มันอ่านง่ายไหม? คำตอบคือ ไม่เลย แล้วถ้าถามว่า มันจำง่ายไหม? คำตอบก็คือ ไม่ เช่นกัน
ตอนนี้สามารถใช้:
คุณจะเห็นว่า มันทั้งสั้นและชัดเจนกว่ามาก
ตัวอย่าง:
มันจะตรวจสอบเฉพาะ Property ของ Object นั้นจริง ๆ ไม่รวม Prototype Chain
3. Top-Level await
ก่อนหน้านี้ ถ้าเราอยากใช้ await เราจำเป็นต้องเขียนมันอยู่ภายใน async Function เท่านั้น
ดังนั้น ต่อให้เป็นงาน Setup ง่าย ๆ เราก็ยังต้อง Wrap ทุกอย่างไว้ใน async Function ซึ่งมันไม่ใช่เรื่องแย่อะไร แต่ก็เป็นขั้นตอนที่เกินความจำเป็น
ตอนนี้สามารถใช้:
ไม่ต้องมี Wrapper ไม่ต้องมี init() Function สามารถเขียน Logic ตรง ๆ ได้เลย
ตัวอย่างที่ 1 — Database Connection
มันเหมาะอย่างมากสำหรับ Backend Script หรือ Node.js Module
ตัวอย่างที่ 2 — Dynamic Imports
สามารถ Load เฉพาะส่วนที่ต้องใช้ โดยไม่ทำให้ Code ยุ่งเหยิง
ตัวอย่างที่ 3 — Load ค่า Environment
มันทำให้ Flow ตอน Startup อ่านง่ายขึ้นมาก
4. Private Class Fields (#)
พูดกันตรง ๆ เลยคือ JavaScript ไม่เคยมี Private Field จริง ๆ
ที่ผ่านมาเรามักตั้งชื่ออย่าง _something แล้วหวังว่าจะไม่มีใครมาแตะต้องมัน แต่นั่นไม่ใช่ Privacy จริง มันก็แค่เป็น Convention เท่านั้น
ตอนนี้สามารถใช้:
แต่ถ้าลองทำแบบนี้:
มันจะ Error ทันที
ตัวอย่าง — Private Methods
จะเห็นว่า Logic ภายในจะยังคงเป็นของภายในจริง ๆ
5. .at() — Relative Indexing
คำถามสุด Classic: จะดึงสมาชิกตัวสุดท้ายของ Array ได้อย่างไร?
พวกเราส่วนใหญ่ น่าจะจำวิธีนี้ได้:
ถึงมันจะใช้งานได้ แต่ก็ไม่สวยสักเท่าไร
ตอนนี้สามารถใช้:
จะเห็นว่า มันอ่านง่ายขึ้นเยอะ
ES2023 — ก้าวสำคัญสู่การจัดการข้อมูลที่ปลอดภัยขึ้น
6. toSorted()
Array.sort() มีประโยชน์มาก แต่ปัญหาคือ มันดันไปเปลี่ยนแปลง Array ต้นฉบับโดยตรง (Mutation) และถ้ามีคนลืมเรื่องนี้เพียงแค่ครั้งเดียว ก็อาจทำให้ State พังได้ในทันที เราก็เลยต้อง Clone Array เองตลอดเวลา
วิธีเดิม:
แม้มันจะใช้งานได้ แต่ต้องเขียนซ้ำ ๆ บ่อยมาก
ตอนนี้สามารถใช้:
จะเห็นว่า ไม่มี Mutation และไม่ต้อง Clone เอง
ตัวอย่าง:
สิ่งที่เปลี่ยนไป:
คุณจะได้ “สำเนาที่ถูก Sort แล้ว” โดยไม่แตะต้องข้อมูลต้นฉบับเลย
7. toReversed() และ toSpliced()
หลักการเดียวกับ toSorted(): มันจะทำการ “Copy” แทนที่จะ Mutation
Reverse (โดยไม่แตะต้อง Array เดิม):
แต่ถ้าใช้วิธีเดิม:
Splice (แต่ไม่ Mutation):
แต่ถ้าใช้วิธีเดิม:
ทำให้ตอนนี้ข้อมูลต้นฉบับ ยังคงปลอดภัย
8. findLast() / findLastIndex()
เราน่าจะใช้งาน find() กันมานานแล้ว แต่ถ้าเราต้องการ “สมาชิกตัวสุดท้าย” ที่ Match กับเงื่อนไขล่ะ
เมื่อก่อน มักต้องเขียนแบบนี้:
เริ่มจาก Clone, Reverse แล้วค่อย Find
ซึ่งที่จริง มันก็ไม่ได้เลวร้ายอะไรนัก แต่มันทั้งยุ่งยากและทำให้สับสนได้ง่าย (โดยเฉพาะสำหรับมือใหม่)
ตอนนี้สามารถใช้:
หรือถ้าต้องการตำแหน่งของมัน:
ไม่ต้อง Reverse ไม่ต้อง Clone แถมอ่านแล้วเข้าใจทันที ว่า Code ต้องการทำอะไร
ES2024 — การจัดการข้อมูลและ Async ที่ฉลาดขึ้น
9. Object.groupBy()
เมื่อก่อน ถ้าจะ Group Array เรามักต้องเขียน Reducer ที่ดูซับซ้อนกว่างานจริงเสียอีก
วิธีเดิม:
มันก็ใช้งานได้ แต่ครั้งแรกที่เห็น ก็ไม่ได้ทำให้รู้สึกว่า อ่านง่ายนัก
วิธีใหม่:
แค่นั้นเอง
ตัวอย่าง:
ผลลัพธ์:
10. Promise.withResolvers()
บางครั้งเราต้องการ Resolve หรือ Reject Promise จากภายนอก ซึ่งที่ผ่านมา วิธีทำมันดู… แปลก ๆ อยู่เสมอ
วิธีเดิม:
ถึงมันจะทำงานได้ แต่ก็ยังไม่ใช่วิธีที่ดีที่สุด
ตอนนี้สามารถใช้:
มันทั้ง ชัดเจน ตรงไปตรงมา แถมไม่ต้องใช้เทคนิคพิเศษอะไรเพิ่มเติม
ตัวอย่าง:
มันเหมาะมากสำหรับ Event-Driven Flow
11. Resizable ArrayBuffer
เมื่อก่อน ArrayBuffer มีขนาดตายตัว
เมื่อสร้างแล้วก็จะมีขนาดเท่านั้นเลย ไม่สามารถขยายและลดขนาดได้อีกแล้ว ซึ่งเป็นเรื่องที่น่าหงุดหงิดมากเวลาที่ต้องทำงานกับ Streaming Data, Workers หรือการทดลองทำอะไรกับข้อมูลแบบ Binary
ตอนนี้สามารถใช้:
เราสามารถ Resize ภายหลังได้แล้ว
ตราบใดที่ยังไม่เกิน maxByteLength
ES2025 — เมื่อ Functional Patterns กลายเป็นเรื่องปกติ
12. Iterator Helpers
Array Methods นั้นยอดเยี่ยมมาก แต่ทุกครั้งที่ใช้ .map(), .filter() หรือ .slice() มันจะสร้าง Array ใหม่เสมอ
ซึ่งสำหรับข้อมูลเล็ก ๆ แล้ว อาจจะไม่เป็นไร แต่ถ้ากับ Dataset ที่มีขนาดใหญ่ นั่นคือ ภาระที่เพิ่มขึ้นมาทันที
วิธีเดิม (สร้าง Array หลายรอบ):
แต่ละขั้นตอน จะมีการสร้าง Array ใหม่ขึ้นมา
วิธีใหม่ (Lazy Processing):
ข้อมูลจะยังไม่ถูก Process จนกว่าจะถูกใช้งานจริง
สิ่งที่มันเข้ามาแทนที่คือ:
- การเขียน Generator Pipeline เองแบบ Manual
- การ Chain Array หลายขั้นที่กิน Performance
- การสร้าง Array ระหว่างทางโดยไม่จำเป็น
13. Set Methods ใหม่
เมื่อก่อน การทำงานกับ Set Operations มักต้องผ่านหลายขั้นตอน โดยเรามักต้อง:
- Convert เป็น Array
- เขียน Filter เอง
- แล้วค่อยแปลงกลับไปเป็น Set
ซึ่งยังไม่ใช่วิธีที่ดูดีที่สุด
วิธีเดิม:
แม้จะอ่านเข้าใจได้ แต่ก็ค่อนข้างยาว
แต่ตอนนี้สามารถใช้:
จะเห็นว่ามันทั้งชัดเจน ตรงไปตรงมา และให้ความรู้สึกเหมือนนิยามทางคณิตศาสตร์จริง ๆ
ตัวอย่าง:
14. RegExp.escape()
การสร้าง Regex จาก Input ของ User เป็นเรื่องที่เสี่ยงมาตลอด
Character พิเศษอย่าง *, ., (, [ อาจทำให้ Pattern ผิดเพี้ยน หรือแย่กว่านั้นคือ อาจก่อให้เกิดปัญหาด้าน Security
วิธีเดิม:
ต้องเขียน Helper สำหรับ Escape เองแทบทุกครั้ง
ตอนนี้สามารถใช้:
จะเห็นว่า มันทั้งใช้งานง่าย, เป็น Built-in และปลอดภัยกว่าเดิม
15. Promise.try()
บางครั้งเราอยากจัดการ Sync และ Async Code ด้วยวิธีเดียวกัน เพราะ Function แบบ Sync อาจ Throw Error กลับมาทันที ในขณะที่ Async Function จะ Reject
แต่ปัญหาคือ พอมีทั้งสองแบบปนกัน ก็จะเริ่มมีความยุ่งยากในเรื่อง Error Handling
วิธีเดิม:
หรือ Wrap แบบ Manual เอง:
ซึ่งอาจดูแปลก ๆ อยู่บ้าง
ตอนนี้สามารถใช้:
ไม่ว่า Function จะ Return ตามปกติ หรือ Throw Error ก็ตาม มันจะถูกแปลงเป็น Promise ให้โดยอัตโนมัติ
ตัวอย่าง:
จะเห็นว่า ตอนนี้ไม่ต้องสนใจแล้วว่า Function นั้นจะ Throw Error หรือ Reject
16. Float16 Support
ปกติ Number ของ JavaScript จะเป็นแบบ 64-bit ซึ่งก็เหมาะกับงานส่วนใหญ่ แต่สำหรับงานที่เน้น Performance สูง มันอาจเกินความจำเป็น
ที่ผ่านมาเรามี Float32Array อยู่แล้ว แต่ตอนนี้ JavaScript ลดลงไปอีกขั้น
มันมีการรองรับ Half-Precision Floating Point แบบ 16-bit แล้ว
สิ่งที่มันหมายถึงจริง ๆ คือ:
- ใช้พื้นที่เก็บข้อมูลน้อยลง (16-bit)
- ลดการใช้ Memory
- ส่งข้อมูลไป GPU / ML ได้เร็วขึ้น
- Buffer มีขนาดกะทัดรัดขึ้น
ตัวอย่าง:
เมื่อทำงานกับ Dataset ขนาดใหญ่ ความแตกต่างในเรื่องของขนาดจะเริ่มเห็นได้ชัดเจนมากขึ้น
ถ้าลองถอยออกมา เพื่อมองภาพรวม เราจะเห็น Pattern ที่ชัดมากขึ้น:
- Mutation น้อยลง
- จุดประสงค์ของ Code แต่ละส่วนชัดเจนขึ้น
- Async Control ปลอดภัยขึ้น
- การจัดการข้อมูลเริ่มไปทาง Functional มากขึ้น
JavaScript ไม่ได้กำลังเข้าสู่ยุค “ปฏิวัติครั้งใหญ่” แต่กำลังถูกพัฒนาปรับปรุงในสิ่งที่มีขนาดเล็กลง แต่สามารถใช้งานได้จริง เช่น
- Methods ขนาดเล็ก
- API ที่ Clean ขึ้น
- Default ที่ดีขึ้น
แม้จะไม่มีอะไรที่หวือหวามากมาย แต่เป็นการอัปเกรดเล็ก ๆ น้อย ๆ ในการใช้งานประจำวันที่ช่วยให้ Code อ่านง่าย, ดูแลรักษาง่าย และทำความเข้าใจได้ง่ายขึ้น
สรุป
และนี่ก็เป็น 16 JavaScript Features ยุคใหม่ที่ช่วยให้เขียน Code ปลอดภัยและอ่านง่ายขึ้น ซึ่งสิ่งที่น่าสนใจของ JavaScript ยุคใหม่ ไม่ใช่การเพิ่ม Syntax ที่ซับซ้อนขึ้น แต่เป็นการออกแบบ Feature เล็ก ๆ ที่ช่วยลด Mutation ทำให้ Intent ของ Code ชัดขึ้น และทำให้การจัดการข้อมูลหรือ Async Flow เป็นธรรมชาติมากกว่าเดิม และเมื่อรวมกัน Features เหล่านี้ก็คืออีกหนึ่งก้าวสำคัญที่ช่วยให้ Dev เขียน Code ได้ปลอดภัย อ่านง่าย และดูแลรักษาได้ง่ายขึ้นในระยะยาว
ที่มา: https://medium.com/
รับตำแหน่งงานไอทีใหม่ๆ ด้วยบริการ IT Job Alert
อัพเดทบทความจากคนวงในสายไอทีทาง LINE ก่อนใคร
อย่าลืมแอดไลน์ @techstarth เป็นเพื่อนนะคะ
บทความล่าสุด















































