กลับไปหน้าบทความ
#JavaScript#Optional Chaining#Nullish Coalescing#Frontend#Clean Code

เขียน JavaScript ให้ปลอดภัยด้วย Optional Chaining และ Nullish Coalescing

บั๊กใน JavaScript จำนวนมากเกิดจากการเข้าถึงข้อมูลที่เป็น null หรือ undefined โดยไม่ทันระวัง บทความนี้จะพาไปรู้จัก Optional Chaining (?.) และ Nullish Coalescing (??) เพื่อเขียนโค้ดให้ปลอดภัย อ่านง่าย และไม่ทำลายค่าที่ควรเ

15 กุมภาพันธ์ 2569อ่านประมาณ 2 นาที

แชร์บทความ

เขียน JavaScript ให้ปลอดภัยด้วย Optional Chaining และ Nullish Coalescing

เขียน JavaScript ให้ปลอดภัยด้วย Optional Chaining และ Nullish Coalescing

หลายครั้งบั๊กในโปรเจกต์ JavaScript ไม่ได้เกิดจากตรรกะที่ซับซ้อน แต่เกิดจากปัญหาง่ายๆ อย่าง “ข้อมูลไม่มา” หรือ “ข้อมูลหายไปบางส่วน” โดยเฉพาะเมื่อทำงานกับ API, user input หรือข้อมูลจากระบบภายนอก

สถานการณ์ที่นักพัฒนามักเจอคือ โค้ดพยายามเข้าถึง property ที่อยู่ลึกหลายชั้น เช่น

user.profile.avatar.url

ถ้า profile กลายเป็น null หรือ undefined เมื่อไร โค้ดจะพังทันทีด้วย TypeError

เพื่อแก้ปัญหานี้ JavaScript มีเครื่องมือสำคัญ 2 ตัวที่ควรรู้จักและใช้ให้คล่อง นั่นคือ Optional Chaining (?.) และ Nullish Coalescing (??)

ปัญหาคลาสสิก: โค้ดพังเพราะข้อมูลไม่ครบ

ในงานจริง response จาก API ไม่ได้สมบูรณ์แบบเสมอไป บางวันมี field นี้ บางวันไม่มี บาง endpoint ส่งค่ามาไม่เหมือนกัน หรือข้อมูลบางส่วนยังโหลดไม่เสร็จ

เมื่อโค้ดไปแตะ property ลึกๆ แบบตรงๆ โดยไม่ป้องกัน เช่น

const url = user.profile.avatar.url

ก็มีโอกาสเกิด error ได้ทันทีหาก user.profile ไม่มีอยู่จริง

นี่คือจุดที่ ?. เข้ามาช่วยให้โค้ดปลอดภัยขึ้นมาก

Optional Chaining (?.): เข้าถึงข้อมูลแบบปลอดภัย

Optional Chaining ใช้สำหรับเข้าถึง property, method หรือ index โดยถ้าค่าด้านซ้ายเป็น null หรือ undefined ระบบจะหยุดทันทีและคืนค่า undefined แทนที่จะ throw error

ตัวอย่างการอ่านค่าลึกๆ

const url = user?.profile?.avatar?.url

โค้ดนี้จะได้ค่า url ถ้ามีข้อมูลครบ แต่ถ้าขาดตรงไหนระหว่างทาง ผลลัพธ์จะเป็น undefined โดยไม่ทำให้โปรแกรมพัง

ใช้กับ method ก็ได้

user?.logout?.()

ถ้า user ไม่มี หรือ logout ไม่ใช่ method ที่มีอยู่จริง โค้ดจะไม่ error และจะไม่เรียกอะไรต่อ

ใช้กับ array index ก็ได้

const first = items?.[0]

มีประโยชน์มากในกรณีที่ items ยังไม่ถูกโหลด หรืออาจไม่มีค่าในบางสถานการณ์

Nullish Coalescing (??): ตั้งค่าเริ่มต้นอย่างถูกต้อง

อีกปัญหาที่พบบ่อยคือการตั้งค่า default ด้วย || ซึ่งดูเหมือนจะสะดวก แต่บางครั้งกลับทำให้ค่าที่ถูกต้องอย่าง 0, false หรือ "" ถูกแทนที่โดยไม่ตั้งใจ

Nullish Coalescing (??) จึงถูกออกแบบมาเพื่อ fallback เฉพาะเมื่อค่าด้านซ้ายเป็น null หรือ undefined เท่านั้น

ตัวอย่างพื้นฐาน

const name = user?.name ?? "Guest"

หาก user.name เป็น null หรือ undefined จะได้ค่า "Guest" แต่ถ้าเป็นสตริงว่าง "" ก็จะยังคงเป็น "" ตามเดิม

เปรียบเทียบกับ ||

const page = query.page || 1

ถ้า query.page = 0 ค่านี้จะถูกเปลี่ยนเป็น 1 ทันที ทั้งที่ 0 อาจเป็นค่าที่มีความหมายในระบบ

การใช้ ?? จะแก้ปัญหานี้ได้

const page = query.page ?? 1

แบบนี้ 0 จะยังคงเป็น 0 ไม่ถูกแทนที่

ตัวอย่างการใช้งานที่เจอบ่อยในงานจริง

เมื่อใช้ ?. และ ?? ร่วมกัน จะช่วยให้โค้ดนิ่งขึ้นและสั้นลงอย่างชัดเจน

1) ตั้งค่าเริ่มต้นให้ config

const timeout = config?.timeout ?? 5000

ถ้า config ไม่มี หรือ timeout ไม่ถูกกำหนด จะใช้ 5000 เป็นค่าเริ่มต้น

2) ดึงค่าจาก API ที่ field อาจหาย

const city = res?.data?.address?.city ?? "-"

เหมาะกับข้อมูลจาก API ที่โครงสร้างอาจไม่แน่นอนทุกครั้ง

3) อ่านค่าที่อาจไม่มีจาก storage

const token = storedToken ?? null

ช่วยให้กำหนดค่าชัดเจนว่า ถ้าไม่มี token ให้เป็น null

4) ใช้คู่กันแบบสั้นและอ่านง่าย

const title = post?.meta?.title ?? "Untitled"

เป็นรูปแบบที่ใช้บ่อยมากในงาน frontend และ backend สมัยใหม่

ทริคเล็กๆ ที่ควรรู้

อีกความสามารถที่น่าสนใจของ Optional Chaining คือ ถ้าด้านซ้ายเป็น null หรือ undefined ฟังก์ชันจะไม่ถูกเรียก

saveUser?.(payload)

ข้อดีคือช่วยลด side effect ที่ไม่คาดคิดในกรณีที่ dependency หรือ callback ยังไม่พร้อมใช้งาน

ข้อควรระวังในการใช้งาน

แม้ ?. จะช่วยลด error ได้ดี แต่ก็มีด้านที่ต้องระวัง เพราะบางครั้งมันอาจทำให้ปัญหาจริงถูกซ่อนเอาไว้แบบเงียบๆ

หากข้อมูลจุดนั้น “ควรต้องมี” ตามสัญญาของระบบ การปล่อยให้คืนค่า undefined อาจทำให้ตรวจเจอปัญหาช้าเกินไป

ดังนั้นแนวทางที่สมดุลคือ

  • ใช้ ?. เมื่อข้อมูลมาจากภายนอกหรือไม่แน่นอน เช่น API, user input, 3rd-party service
  • ใช้ validation หรือ throw error เมื่อข้อมูลนั้นเป็นสิ่งที่ระบบกำหนดว่าต้องมีแน่นอน

การเลือกใช้ให้ถูกบริบทจะทำให้โค้ดทั้งปลอดภัยและยังตรวจจับปัญหาได้เหมาะสม

แนวทาง refactor โค้ดให้ดีขึ้น

หากในโปรเจกต์มีโค้ดลักษณะ if ซ้อนหลายชั้นเพื่อตรวจว่า object แต่ละระดับมีค่าหรือไม่ นั่นมักเป็นสัญญาณว่าคุณสามารถ refactor ให้สั้นลงและอ่านง่ายขึ้นด้วย ?. และ ??

จากโค้ดที่ยาวและซับซ้อน การเปลี่ยนมาใช้ syntax เหล่านี้จะช่วยให้ intent ของโค้ดชัดขึ้นทันที ว่ากำลัง “เข้าถึงแบบปลอดภัย” และ “ตั้งค่าเริ่มต้นแบบไม่ทำลายค่าที่ถูกต้อง”

สรุป

Optional Chaining (?.) ช่วยป้องกันโค้ดพังเมื่อเจอ null หรือ undefined ระหว่างทาง ส่วน Nullish Coalescing (??) ช่วยตั้งค่า default ได้อย่างแม่นยำโดยไม่ไปทับค่าอย่าง 0, false หรือ ""

เมื่อใช้ทั้งสองอย่างร่วมกัน คุณจะได้โค้ด JavaScript ที่อ่านง่ายขึ้น ปลอดภัยขึ้น และเหมาะกับโลกจริงที่ข้อมูลไม่ได้สมบูรณ์เสมอไป หากอยากยกระดับโค้ดให้โปรขึ้น ลองเริ่มจากจุดที่มีการเช็กข้อมูลหลายชั้น แล้วค่อย refactor ด้วย ?. และ ?? แล้วจะเห็นความต่างชัดเจน