ฟีเจอร์ที่นักพัฒนา JavaScript ต้องรู้ในปี 2025
(waspdev.com)- JavaScript ยังคงพัฒนาอย่างต่อเนื่องในปี 2025 และมีบางฟีเจอร์ที่อาจไม่ค่อยเป็นที่รู้จักแต่มีประโยชน์มาก
- เมธอดช่วยเหลือของ Iterator ชุดใหม่ทำงานได้อย่าง มีประสิทธิภาพด้านหน่วยความจำ มากกว่ามากเมื่อแปลงข้อมูลขนาดใหญ่
- การเข้าถึงจากท้ายอาร์เรย์ด้วย
at(), การใช้Promise.withResolvers()ที่เรียบง่าย, และstructuredClone()สำหรับการคัดลอกแบบลึก - การดำเนินการเซตสำหรับ Set, ฟังก์ชันแท็กของ template string, และ วิธีใช้ WeakMap/WeakSet ยังคงเป็นสิ่งที่นักพัฒนาจำนวนมากมองข้าม
เมธอดช่วยเหลือของ Iterator
- การเชนแบบเดิมอย่าง
arr.filter().map()นั้น ไม่มีประสิทธิภาพเพราะสร้างอาร์เรย์ใหม่ในทุกขั้นตอน - สามารถปรับปรุงได้ด้วย การเชนบนพื้นฐานของ iterator เช่น
arr.values().drop(10).take(10).map(...).toArray() - เมธอดหลัก:
drop(): ข้าม n รายการแรกtake(): เอาเฉพาะ n รายการแรกfilter(),map(),flatMap(): ทำงานคล้ายเมธอดของอาร์เรย์reduce(),some(),every(),find(): รองรับการทดสอบเงื่อนไขและการคำนวณสะสมtoArray(): แปลงเป็นอาร์เรย์สุดท้าย
- Safari เริ่มรองรับตั้งแต่ 31 มีนาคม 2025 แต่ตอนนี้ยังไม่รองรับทุกเบราว์เซอร์
Array at()
arr.at(n)คล้ายกับarr[n]แต่ เข้าถึงจากท้ายได้ด้วยดัชนีติดลบ- ตัวอย่าง:
[10, 20, 30].at(-1)→30 - จึงเข้าถึงสมาชิกตัวสุดท้ายได้โดยไม่ต้องใช้วิธีที่ยุ่งยากอย่าง
arr[arr.length - 1]
Promise.withResolvers()
- วิธีเดิม: เก็บ
resolve/rejectจากภายนอกในnew Promise((resolve, reject) => { ... }) - ตอนนี้สามารถใช้แบบ กระชับและตรงไปตรงมา ได้ด้วย
const { promise, resolve, reject } = Promise.withResolvers()
การใช้คอลแบ็กกับ String.replace()
- อาร์กิวเมนต์ตัวที่สองของ
replace()และreplaceAll()รองรับได้ไม่ใช่แค่สตริง แต่รวมถึงฟังก์ชันคอลแบ็กด้วย - ตัวอย่าง:
"X, X, X".replaceAll("X", (match, i) => match + i)→"X0, X3, X6" - ทำการแทนที่ได้หลากหลายภายในครั้งเดียว → มีประสิทธิภาพทั้งด้าน performance และหน่วยความจำ
การสลับตัวแปร (Swap)
- วิธีเดิม: ใช้ตัวแปร
temp - วิธีที่กระชับกว่า:
[a, b] = [b, a]เพื่อ สลับตัวแปรด้วย array destructuring
structuredClone()
- รองรับการคัดลอกแบบลึกที่ แม่นยำและมีประสิทธิภาพกว่า
JSON.stringify()+JSON.parse() - ข้อดี:
- รองรับ
NaN,undefined,bigintเป็นต้น - คัดลอก circular reference ได้อย่างปลอดภัย
- ใช้หน่วยความจำและทำงานได้เร็วกว่า เมื่อจัดการอ็อบเจ็กต์ขนาดใหญ่
- รองรับ
Tagged Template Literals
- สามารถพาร์ส template string ผ่านฟังก์ชันเฉพาะได้
- มีประโยชน์สำหรับ การประมวลผลสตริงแบบไดนามิกภายหลัง เช่น การ escape HTML
- ตัวอย่าง:
ฟังก์ชันแท็กescapeHtmlทำให้<br> ${'<br>'}→<br> &lt;br&gt;
WeakMap / WeakSet
- คล้ายกับ
Map,Setปกติ แต่:- อนุญาตให้ใช้เฉพาะอ็อบเจ็กต์เป็นคีย์ (ไม่รองรับ primitive)
- หากกลายเป็นเป้าหมายของ GC จะถูกลบออกโดยอัตโนมัติ
- เหมาะสำหรับกรณีที่อาจมี circular reference หรือเมื่อต้องการ เก็บ metadata ของอ็อบเจ็กต์โดยไม่ก่อให้เกิด side effect
รองรับการดำเนินการเซตสำหรับ Set
ใน JavaScript มีการเพิ่ม logical operations หลากหลายแบบให้กับอ็อบเจ็กต์ Set:
difference(): ผลต่างเซต (A - B)intersection(): อินเตอร์เซกชัน (A ∩ B)union(): ยูเนียน (A ∪ B)symmetricDifference(): symmetric difference (A △ B)isDisjointFrom(): มีสมาชิกที่ซ้อนทับกันหรือไม่isSubsetOf(): เป็นสับเซตหรือไม่isSupersetOf(): เป็นซูเปอร์เซตหรือไม่
4 ความคิดเห็น
ดูเหมือนว่าปัญหาที่เมื่อพาร์สลิเทอรัลแล้วแม้แต่ตัวแปรก็ออกมาเป็นสตริงได้รับการแก้ไขแล้ว ขอบคุณที่แชร์ครับ
ตัวอย่าง:
"X, X, X".replaceAll("X", (match, i) => match + i)→"X0, X1, X2"ตัวอย่างนี้ไม่ถูกต้อง
iมีตำแหน่งที่พบอยู่ดังนั้นค่าผลลัพธ์จึงเป็น
"X0, X3, X6"ครับอ้อ จริงด้วยครับ AI สร้างตัวอย่างผิดไปเอง ผมแก้ไขไว้แล้ว ขอบคุณสำหรับการทักท้วงที่เฉียบคมครับ!
valuesให้ความรู้สึกคล้าย Java Stream API เลยลองเทียบดู พบว่าถ้าขนาดของ array เล็ก การใช้filterโดยไม่ผ่านvaluesจะเร็วกว่านิดหน่อยครับ เพราะเป็นแบบ iterator ยิ่งมีการ chaining มากขึ้น วิธีที่ผ่านvaluesหนึ่งรอบก็น่าจะยิ่งมีผลให้เร็วขึ้นได้เหมือนกัน ดู benchmark ได้ที่ https://jsperf.app/dixutu