JavaScript
Number Methods
Math.random
เรียนรู้ Math.random() สำหรับสุ่มเลข สร้างช่วงตัวเลขที่ต้องการ และสุ่มเลือกจาก array
Math.random() สุ่มเลขระหว่าง 0 ถึง 1
`Math.random()` คืนค่าเลขทศนิยมแบบสุ่มในช่วง **[0, 1)** — คือตั้งแต่ `0` จนถึงเกือบ `1` (ได้ `0` ได้ แต่**ไม่เคยได้ `1` เป๊ะ**) ใช้งานง่ายที่สุดในบรรดา Math methods เพราะ: - **ไม่รับ argument** — เรียกเฉย ๆ ได้เลย - คืนค่าเป็น `number` ทุกครั้ง - ทุกครั้งที่เรียกจะได้ค่าต่างกัน
console.log(Math.random()); // 0.374529...(เปลี่ยนทุกครั้ง)
console.log(Math.random()); // 0.950714...
console.log(Math.random()); // 0.731994...
// ผลลัพธ์เป็นทศนิยมในช่วง [0, 1)
const r = Math.random();
console.log(r >= 0); // true — ค่าต่ำสุดคือ 0
console.log(r < 1); // true — ไม่เคยถึง 1
console.log(r === 1); // false — ไม่มีวันได้ 1- `Math.random()` ไม่รับ argument — เรียก `Math.random()` เฉย ๆ
- คืนค่าเป็นทศนิยมในช่วง **[0, 1)** — ได้ 0 ได้ แต่ไม่เคยได้ 1
- ทุกครั้งที่เรียกจะได้ค่าใหม่ — ไม่ซ้ำกับครั้งก่อน
- เป็น **pseudo-random** — สร้างจากอัลกอริทึม ไม่ใช่การสุ่มแท้จริง
สร้างเลขจำนวนเต็มสุ่มด้วย Math.floor + Math.random
ถ้าต้องการเลขจำนวนเต็มแบบสุ่ม เรานำ `Math.random()` ไปคูณแล้วใช้ `Math.floor()` ปัดลง สูตรพื้นฐาน: `Math.floor(Math.random() * n)` → ได้เลขจำนวนเต็มตั้งแต่ **0 ถึง n-1** ทำไมต้อง `Math.floor`: 1. `Math.random()` ได้ทศนิยมในช่วง [0, 1) 2. คูณด้วย `n` → ได้ทศนิยมในช่วง [0, n) 3. `Math.floor()` ปัดลง → ได้จำนวนเต็ม 0, 1, 2, ..., n-1
// n = 3 → ได้ 0, 1, หรือ 2
console.log(Math.floor(Math.random() * 3)); // 0, 1, หรือ 2
// n = 10 → ได้ 0 ถึง 9
console.log(Math.floor(Math.random() * 10)); // 0-9
// n = 100 → ได้ 0 ถึง 99
console.log(Math.floor(Math.random() * 100)); // 0-99
// ตรวจสอบช่วง
const n = 10;
const result = Math.floor(Math.random() * n);
console.log(result >= 0); // true
console.log(result <= n - 1); // true (ไม่เกิน 9)ทำไมไม่ใช้ Math.round?
ถ้าใช้ `Math.round(Math.random() * 10)` จะได้ 0-10 แต่**การกระจายไม่สม่ำเสมอ**: - 0 มีโอกาสเกิดแค่ช่วง [0, 0.5) — น้อยกว่า - 5 มีโอกาสเกิดช่วง [4.5, 5.5) — มากกว่า - 10 มีโอกาสเกิดแค่ช่วง [9.5, 10) — น้อยกว่า `Math.floor()` แบ่งช่วงเท่ากันหมด → แต่ละตัวเลขมีโอกาสเกิดเท่ากัน
- สูตร: `Math.floor(Math.random() * n)` → ได้จำนวนเต็ม 0 ถึง n-1
- ใช้ `Math.floor` เท่านั้น — เพื่อให้แต่ละตัวเลขมีโอกาสเกิดเท่ากัน
- อย่าใช้ `Math.round` — จะทำให้ตัวเลขปลายทางเกิดน้อยกว่าตัวกลาง
- อย่าใช้ `Math.ceil` — `Math.ceil(0)` ได้ 0 แต่ `Math.ceil(0.001)` ได้ 1 ทำให้ 0 เกิดน้อยมาก
สุ่มเลขในช่วง min ถึง max
สูตรสุ่มเลขจำนวนเต็มในช่วง **[min, max]** (รวม min และ max): ``` Math.floor(Math.random() * (max - min + 1)) + min ``` อธิบายทีละส่วน: 1. `max - min + 1` = จำนวนค่าที่เป็นไปได้ (เช่น 1-6 → มี 6 ค่า) 2. `Math.random() * (จำนวนค่า)` → ทศนิยมในช่วง [0, จำนวนค่า) 3. `Math.floor(...)` → จำนวนเต็ม 0 ถึง (จำนวนค่า - 1) 4. `+ min` → เลื่อนช่วงไปเริ่มที่ min
// ลูกเต๋า: 1-6
const dice = Math.floor(Math.random() * 6) + 1;
console.log(dice); // 1, 2, 3, 4, 5, หรือ 6
// เดือน: 1-12
const month = Math.floor(Math.random() * 12) + 1;
console.log(month); // 1-12
// คะแนน: 0-100
const score = Math.floor(Math.random() * 101);
console.log(score); // 0-100
// เลขสองหลัก: 10-99
const twoDigit = Math.floor(Math.random() * 90) + 10;
console.log(twoDigit); // 10-99- สูตร: `Math.floor(Math.random() * (max - min + 1)) + min`
- `max - min + 1` = จำนวนค่าที่เป็นไปได้ (เช่น 1-6 → 6 ค่า)
- สำหรับช่วง [0, n] สูตรย่อเป็น `Math.floor(Math.random() * (n + 1))`
- ถ้าช่วงเริ่มที่ 1 เสมอ → `Math.floor(Math.random() * n) + 1`
การใช้จริง: สุ่มเลือกจาก array
การใช้ `Math.random()` ที่พบบ่อยที่สุดอย่างหนึ่งคือ **สุ่มเลือก element จาก array** สูตร: `array[Math.floor(Math.random() * array.length)]` เราใช้ `Math.floor` กับ `array.length` เพื่อให้ได้ index ที่ถูกต้องเสมอ (0 ถึง length-1) — ไม่มีโอกาสได้ index เกินขอบเขต
const colors = ["red", "green", "blue", "yellow", "purple"];
// สุ่ม index ที่ปลอดภัย (0 ถึง 4)
const randomIndex = Math.floor(Math.random() * colors.length);
const randomColor = colors[randomIndex];
console.log(randomIndex); // 0, 1, 2, 3, หรือ 4
console.log(randomColor); // "red", "green", "blue", "yellow", หรือ "purple"const days = ["จันทร์", "อังคาร", "พุธ", "พฤหัสบดี", "ศุกร์", "เสาร์", "อาทิตย์"];
const randomDay = days[Math.floor(Math.random() * days.length)];
console.log("สุ่มได้วัน" + randomDay);- ใช้ `Math.floor(Math.random() * array.length)` เพื่อสุ่ม index ที่ถูกต้องเสมอ
- ไม่ต้องกังวลเรื่อง index เกินขอบเขต — `Math.floor` รับประกันว่าได้ 0 ถึง length-1
- ทุก element มีโอกาสถูกเลือกเท่ากัน เพราะใช้ `floor` ไม่ใช่ `round`
- เป็น pattern ที่ใช้บ่อย: สุ่ม quote, สุ่มคำถาม, สุ่มชื่อ, สุ่มสี
ข้อจำกัดของ Math.random และข้อควรระวัง
`Math.random()` เป็น **pseudo-random number generator (PRNG)** — สร้างเลขจากอัลกอริทึม ไม่ใช่การสุ่มแท้จริงจากแหล่งกำเนิดฟิสิกส์ สิ่งที่ `Math.random()` **ทำไม่ได้**: - **ไม่ปลอดภัยสำหรับการเข้ารหัส** — ใครก็ตามที่รู้ seed สามารถทำนายผลได้ - **กำหนด seed เองไม่ได้** — ไม่มีวิธีทำให้ผลซ้ำเดิมได้ - **ไม่เหมาะกับสถานการณ์ที่ต้องการความปลอดภัยสูง** ถ้าต้องการเลขสุ่มที่ปลอดภัยทาง cryptography ให้ใช้ `crypto.getRandomValues()` แทน
// เรียก 5 ครั้ง → ได้ค่าต่างกันทุกครั้ง
for (let i = 0; i < 5; i++) {
console.log(Math.random());
}
// 0.374529...
// 0.950714...
// 0.731994...
// 0.598658...
// 0.156018...
// ❌ ไม่สามารถทำให้ผลซ้ำได้ — ไม่มี seed
// ❌ ไม่ปลอดภัยสำหรับ password, token, หรือการเข้ารหัสห้ามใช้ Math.random กับข้อมูลที่ต้องการความปลอดภัย
อย่าใช้ `Math.random()` สำหรับ: - สร้าง password หรือ token - สร้าง session ID - การเข้ารหัส (encryption) - สร้าง secret key สำหรับกรณีเหล่านี้ ให้ใช้ `crypto.getRandomValues()` แทน (มีใน browser และ Node.js)
- `Math.random()` เป็น pseudo-random — สร้างจากอัลกอริทึม ไม่ใช่การสุ่มแท้
- ใช้ได้ดีกับ: เกม, สุ่มแสดงเนื้อหา, mock data, animation, A/B testing
- ห้ามใช้กับ: password, token, session ID, encryption — ใช้ `crypto.getRandomValues()` แทน
- ไม่สามารถกำหนด seed เพื่อให้ผลซ้ำได้