top of page
ค้นหา

JavaScript "isNaN(true)" returns false

  • รูปภาพนักเขียน: Sathit Jittanupat
    Sathit Jittanupat
  • 13 ธ.ค. 2567
  • ยาว 1 นาที

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


isNaN

ที่มาของเรื่อง ผมออกแบบคำสั่ง config ในโปรแกรมให้สามารถกำหนดเป็น true , false , หรือตัวเลขใดๆ ก็ได้ 


ใช้สำหรับควบคุมเงื่อนไขการบันทึก log เมื่อมีใครเปลี่ยนการตั้งค่าการทำงาน


  • false บันทึก log โดยไม่ต้องแจ้งเตือน

  • true แจ้งเตือนทุกครั้งให้ระบุเหตุผลของการแก้ไข ก่อนบันทึก log

  • ตัวเลข จำนวนวันที่ต้องการเว้นช่วงแจ้งเตือน เช่น 1 หมายถึง ภายใน 1 วันหากมีการแก้ไขหลายครั้ง จะแจ้งเตือนให้บันทึกเหตุผลแค่ครั้งแรกครั้งเดียว


ความตั้งใจของผม เปิดให้เลือกกำหนดเงื่อนไขสำหรับแต่ละโปรเจคท์ได้เอง เผื่อว่าไม่อยากให้โปรแกรมแจ้งเตือนถามเหตุผลพร่ำเพรื่อเกินไป บางครั้งช่วงที่ขึ้นระบบใหม่การตั้งค่าอาจติดพันต่อเนื่อง ซึ่งแตกต่างจากช่วงที่ระบบลงตัวแล้ว อารมณ์ของคนทำงานจะต่างกัน


ree

NaN ย่อมาจาก Not A Number ตามความเข้าใจ(ผิด)ของผม จึงใช้คำสั่ง isNaN ตรวจสอบว่าค่านั้นเป็นตัวเลขหรือไม่ โดยคาดหวังว่า isNaN(true) ควรได้ผลลัพธ์ว่า ไม่เป็นตัวเลข


หลังจากที่อัพเดทโปรแกรมไปใช้งานไปได้สองวัน กลับมาตรวจสอบการทำงาน ปรากฏว่าเมื่อตั้งค่าเป็น true กลับไม่ยอมแจ้งเตือนให้ระบุเหตุผลทุกครั้ง แต่ทำงานเหมือนกับใส่ค่าตัวเลขจำนวนวัน พยายามตรวจสอบโน่นนี่นั่น จนสุดท้ายก็เลย เอ๊ะ หรือว่า true จะถูกตีความว่าเป็นค่าตัวเลข (enum) เหมือนบางภาษา


สรุปว่าจริงตามนั้น ทีแรกเข้าใจเอาเองว่าเฉพาะ Number (integer/float) หรือ ข้อความตัวเลขเท่านั้น อะไรที่ดูไม่เหมือนตัวเลขไม่ควรนับรวม ไม่คิดว่า Boolean, Array หรือ Empty String จะถูกเหมารวมว่าเป็นค่าตัวเลขด้วย โอ มายก็อด


  • Boolean isNaN(true) และ isNaN(false) เธอตอบว่าเป็นตัวเลข  เพราะ +true มีค่าเป็น 1 และ +false มีค่าเป็น 0

  • Empty String isNaN("") และ isNaN(" ") มีหรือไม่มี space อยู่ด้วย ก็ตอบว่าเป็นตัวเลข เราสามารถแปลงเป็น Number ด้วยคำสั่ง (+"") ได้เท่ากับ 0 รวมทั้ง isNaN(" 1") ก็ถือว่าเป็นตัวเลขเหมือนกัน

  • Array isNaN([]) และ isNaN([""]) และ isNaN([" "]) เธอก็ยังบอกว่าเป็นตัวเลขเช่นกัน ขัดความรู้สึกยังไงก็ไม่รู้ 


คนเขียน JavaScript น่าจะเป็นคนที่เข้าใจอารมณ์ซับซ้อนของคนอื่นได้ดี


ree

สำหรับกรณีของผม แก้ไขโดยเขียนโค้ดได้ประมาณนี้


if (alert && alert!==true && !isNaN(alert)) 

เมื่อเข้าใจแล้วไม่ยาก หาทางเขียนโค้ดตรวจละเอียดตามวัตถุประสงค์กันเองนะครับ


Math.round

แถมเล่าเรื่องหลุมพรางเก่าให้อีกสั้นๆ เคยเขียนเล่าไปแล้ว เจอตอนที่ทำใบลดหนี้ปัดเศษคำนวณภาษี


กรณีค่าสินค้ามีเศษสตางค์ .50 แล้วคำนวณภาษีอัตรา 7% 


  • ปกติค่าสินค้า 10.50 คำนวณภาษีได้ 0.735 ปัดเศษเป็น 0.74 

    เราสามารถใช้คำสั่ง Math.round(10.50 * 7) / 100 ได้ 0.74 ถูกต้อง

  • ถ้าลดหนี้เป็นค่าติดลบ -10.50 คำนวณภาษีได้ -0.735 ก็ควรปัดเศษเป็น -0.74

    แต่ Math.round(-10.50 * 7) / 100 กลับได้ 0.73 ไม่เท่ากัน


กลายเป็นว่าตอนลดหนี้คืนเงินค่าภาษีไม่ครบ 


ree

เรื่องนี้ใครใช้ JavaScript แล้วคำนวณปัดเศษต้องระวังให้ดี 


ผมแก้โดยเขียนฟังก์ชั่น round ใช้เอง ตรวจก่อน ถ้าเป็นค่าลบให้กลับเป็นค่าบวกคำนวณปัดเศษ เสร็จ แล้วค่อยกลับค่าเป็นลบ


อ้างอิง


 
 
 

ความคิดเห็น


Post: Blog2_Post
  • Facebook

©2020 by Scraft On Cloud. Proudly created with Wix.com

bottom of page