วัตถุ Math ของ JavaScript เปรียบเสมือนเข็มขัดเครื่องมือที่ทำงานอย่างเงียบเชียบของภาษานี้ คุณไม่จำเป็นต้องสร้างอินสแตนซ์ (instantiate) และไม่ต้องนำเข้า (import) มัน มันมีอยู่แล้วในทุก runtime พร้อมที่จะจัดการทุกอย่าง ตั้งแต่การปัดเศษค่าพิกเซลไปจนถึงการสุ่มผลลัพธ์จากการทอยลูกเต๋า เนื่องจาก Math เป็นวัตถุแบบ static ทุกเมธอดและพร็อพเพอร์ตี้จึงผูกติดกับ namespace โดยตรง คุณเขียน Math.PI ไม่ใช่ new Math().PI การออกแบบเช่นนี้ช่วยให้ทุกอย่างเรียบง่าย แต่ก็หมายความว่าวัตถุนี้มี "เหลี่ยมคม" บางอย่างที่ควรทำความเข้าใจก่อนที่คุณจะนำไปใช้ในตรรกะระดับ production
วัตถุแบบ Static ที่ไม่มี Constructor
วัตถุพื้นฐานส่วนใหญ่ใน JavaScript ต้องการให้คุณสร้างอินสแตนซ์ขึ้นมา คุณเรียกใช้ new Date() หรือ new Array() แต่ Math ปฏิเสธสิ่งนั้น มันถูกออกแบบมาให้เป็น namespace ของฟังก์ชันและค่าคงที่ที่เกี่ยวข้องซึ่งทำงานกับประเภทข้อมูลพื้นฐาน (primitive) แบบ Number เรียก Math.sqrt(16) แล้วคุณจะได้ 4 แต่ถ้าลองใช้คีย์เวิร์ด new เอนจินจะโยน TypeError ออกมา รูปแบบนี้ช่วยให้การจัดการหน่วยความจำสะอาดและเป็นการส่งสัญญาณว่า Math เป็นแบบ functional บริสุทธิ์ คือรับอินพุต ส่งเอาต์พุต และไม่มีการเปลี่ยนแปลงค่า (mutate) ใดๆ
มีข้อจำกัดที่สำคัญหนึ่งอย่างที่ต้องจำคือ Math ทำงานกับตัวเลขมาตรฐาน IEEE 754 และไม่รองรับ BigInt หากคุณส่ง BigInt ไปยัง Math.round() หรือ Math.abs() คุณจะได้รับ TypeError หากแอปพลิเคชันของคุณต้องจัดการกับจำนวนเต็ม 64 บิตหรือใหญ่กว่านั้น คุณจำเป็นต้องแปลงค่าลงมา หรือจัดการการคำนวณด้วยตัวดำเนินการ (operators) ของ BigInt โดยตรงแทน
ค่าคงที่ที่คุณใช้งานจริง
วัตถุ Math เปิดเผยค่าคงที่ทางตัวเลขหลายค่าที่ช่วยให้คุณไม่ต้องเขียน "magic numbers" ลงไปในโค้ดโดยตรง
Math.PIคือค่า 3.14159... ที่คุ้นเคย ซึ่งจำเป็นสำหรับทุกอย่างที่เกี่ยวข้องกับวงกลม ตรีโกณมิติ หรือการแปลงองศาเป็นเรเดียนMath.Eคือค่าของออยเลอร์ (Euler's number) ซึ่งมีค่าประมาณ 2.718 มักปรากฏในกราฟการเติบโตแบบเอกซ์โพเนนเชียล การคำนวณดอกเบี้ยทบต้น และสเกลลอการิทึมMath.SQRT2คือรากที่สองของสอง มีค่าประมาณ 1.414 มีประโยชน์เมื่อคุณต้องการหาเส้นทแยงมุมของรูปสี่เหลี่ยมจัตุรัส หรือต้องการทำ normalize เวกเตอร์ในเรขาคณิตพื้นฐานMath.LN2คือลอการิทึมธรรมชาติของ 2 มีค่าประมาณ 0.693 คุณจะพบสิ่งนี้ในอัลกอริทึมที่จัดการกับ binary trees, เอนโทรปีของข้อมูล หรือการวิเคราะห์ความซับซ้อนของเวลา (time complexity) ที่เกี่ยวข้องกับคณิตศาสตร์ฐาน log-2
ค่าเหล่านี้เป็นทศนิยมแบบ double-precision floats อย่างเต็มรูปแบบ และเนื่องจากเป็นพร็อพเพอร์ตี้ไม่ใช่เมธอด คุณจึงเข้าถึงได้โดยไม่ต้องใช้เครื่องหมายวงเล็บ
การปัดเศษ, เครื่องหมาย และค่าสัมบูรณ์
งานด้าน Math ที่พบบ่อยที่สุดคือการจัดการตัวเลขให้เรียบร้อย JavaScript มีเมธอดการปัดเศษให้คุณสี่แบบ ซึ่งแต่ละแบบมีพฤติกรรมไม่เหมือนกัน โดยเฉพาะเมื่อคุณเริ่มทำงานกับค่าที่ติดลบ
Math.abs(x) คืนค่าขนาด (magnitude) ของตัวเลข หากส่ง -42 เข้าไป คุณจะได้ 42 มันมีประโยชน์เมื่อคุณสนใจระยะทางมากกว่าทิศทาง เช่น การเปรียบเทียบ timestamps, การคำนวณค่าความต่าง (delta) ใน UI หรือการตรวจสอบว่าค่าที่เดาไว้อยู่ในขอบเขตความคลาดเคลื่อนหรือไม่
Math.round(x) คือการปัดเศษแบบพื้นฐานที่เรียนในโรงเรียน มันจะเลือกจำนวนเต็มที่ใกล้ที่สุด โดยจะปัดค่า .5 ขึ้นไปยังจำนวนเต็มบวกถัดไป เช่น 4.4 กลายเป็น 4 และ 4.5 กลายเป็น 5
Math.ceil(x) จะปัดขึ้นไปยังจำนวนเต็มถัดไปเสมอ 4.1 กลายเป็น 5 และ -4.9 กลายเป็น -4 ซึ่งกรณีหลังนี้มักทำให้คนแปลกใจ เพราะ -4 มีค่ามากกว่า -4.9 บนเส้นจำนวน ดังนั้น ceiling จึงเคลื่อนเข้าหาศูนย์สำหรับค่าลบ
Math.floor(x) ทำงานตรงกันข้าม มันจะปัดลงเสมอ 4.9 กลายเป็น 4 และ -4.1 กลายเป็น -5 หากคุณกำลังทำ pagination สำหรับผลการค้นหาหรือการจัดสรรหน่วยความจำขนาดคงที่ floor มักจะเป็นสิ่งที่คุณต้องการ
Math.trunc(x) จะตัดทศนิยมทิ้งทั้งหมด เหลือเพียงส่วนที่เป็นจำนวนเต็ม ในทางปฏิบัติ มันจะเคลื่อนเข้าหาศูนย์ไม่ว่าเครื่องหมายจะเป็นอะไรก็ตาม 4.9 กลายเป็น 4 และ -4.9 กลายเป็น -4 หากคุณกำลังพอร์ตตรรกะจากภาษาที่แปลง float เป็น int ด้วยการตัดเศษ (truncating) นี่คือตัวช่วยของคุณ
สุดท้าย Math.sign(x) จะบอกว่าค่าที่ส่งเข้าไปอยู่ฝั่งไหนของศูนย์ โดยจะคืนค่า 1 สำหรับค่าบวก, -1 สำหรับค่าลบ, 0 สำหรับ positive zero, -0 สำหรับ negative zero และ NaN สำหรับสิ่งที่ไม่ใช่ตัวเลข เป็นวิธีที่สั้นและกระชับในการแยกเงื่อนไขตามทิศทางโดยไม่ต้องเขียน if-else หลายชั้น
การสุ่มตัวเลข
Math.random() ผลิตค่าทศนิยมแบบ pseudo-random ตั้งแต่ 0 (รวม 0) ถึง 1 (ไม่รวม 1) มันไม่ได้มีความปลอดภัยทางด้านวิทยาการรหัสลับ (cryptographically secure) ดังนั้นอย่าใช้มันในการสร้างรหัสผ่าน, การสร้าง token หรืออะไรก็ตามที่เกี่ยวข้องกับเงินจริง
