السلاح السري لـ JS: توليد أرقام عشوائية بأقصى أداء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

هل الصدفة غير عشوائية؟ كيف تجعل JavaScript يصدر أرقامًا "عادلة"

\n\n

تخيل: أنت تكتب لعبة يظهر فيها العدو في نقطة عشوائية على الشاشة. أو تنشئ اختبار A/B يوزع المستخدمين بالتساوي على المجموعات. أو ببساطة تريد توليد كلمة مرور عشوائية. في كل هذه الحالات، ستحتاج إلى نفس السحر — توليد رقم عشوائي بين قيمتين في JavaScript.

\n\n

قد يبدو الأمر بسيطًا؟ Math.random() — وخلاص. ولكن كما يظهر السؤال الشائع على Stack Overflow (ملايين المشاهدات، آلاف الأصوات)، يكمن الشيطان في التفاصيل. يمكن أن يؤدي التنفيذ غير الصحيح إلى انحياز (bias) في التوزيع، وبطء في الأداء، وأخطاء غير متوقعة.

\n\n

في هذه المقالة، لن نقدم فقط كودًا جاهزًا. سنقوم بتحليل تشريحه، ونتعلم كيفية تحسينه لسيناريوهات مختلفة، ونفهم كيفية جعل التوليد أقصى أداء. هيا بنا!

\n\n

الأساسيات: Math.random() ولماذا لا يكفي وحده

\n\n

في قلب أي توليد للأرقام العشوائية في JS تكمن الطريقة Math.random(). إنها تُرجع رقمًا عشوائيًا زائفًا (pseudo-random) بفاصلة عائمة من النطاق [0, 1) (يشمل 0، لكنه لا يشمل 1 أبدًا).

\n\n
console.log(Math.random()); // 0.234567890123456\nconsole.log(Math.random()); // 0.987654321098765
\n\n

هذه قاعدة ممتازة، لكنها غير مفيدة إذا كنت بحاجة إلى رقم من 5 إلى 10 أو من -100 إلى 100. نحتاج إلى دالة لتوليد رقم عشوائي في نطاق محدد.

\n\n

الإجابة القانونية من Stack Overflow

\n\n

الحل الأكثر شيوعًا وصحة يبدو كالتالي:

\n\n
function getRandomArbitrary(min, max) {\n  return Math.random() * (max - min) + min;\n}
\n\n
    \n
  • كيف يعمل: (max - min) هو عرض النطاق. بضربه في Math.random()، نحصل على رقم من 0 إلى العرض. بإضافة min، نزيح النتيجة إلى النطاق المطلوب.
  • \n
  • النتيجة: رقم كسري من min (شامل) إلى max (غير شامل).
  • \n
\n\n

ولكن ماذا لو كنت بحاجة إلى عدد صحيح؟ هنا يأتي دور Math.floor() و Math.ceil() و Math.round().

\n\n

توليد عدد صحيح عشوائي: الشيطان في التقريب

\n\n

الجزء الثاني من الإجابة على Stack Overflow هو دالة الأعداد الصحيحة:

\n\n
function getRandomInt(min, max) {\n  min = Math.ceil(min);\n  max = Math.floor(max);\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}
\n\n

لاحظ + 1 في النهاية. هذه تفصيلة بالغة الأهمية. بدونها، لن تظهر القيمة القصوى max أبدًا، لأن Math.random() لا تُرجع أبدًا 1 بالضبط.

\n\n

لماذا Math.ceil() و Math.floor()؟

\n

هذا حماية من الأخطاء. إذا قام شخص بتمرير min = 1.5 إلى الدالة، فإن Math.ceil(1.5) يحولها إلى 2. و Math.floor(9.9) يحولها إلى 9. هذا يضمن إدخالًا صحيحًا ونتيجة متوقعة.

\n\n

تحسين الأداء: مقارنة الأساليب

\n\n

الآن الجزء المثير للاهتمام — أداء توليد الأرقام العشوائية في JavaScript. لنفترض أنك بحاجة إلى إنشاء 10,000 نقطة عشوائية على canvas. كل ملي ثانية لها أهميتها.

\n\n

اختبرنا ثلاثة أساليب:

\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
الأسلوبالكودالوقت (10 ملايين تكرار)
التقليدي (مع التقريب)Math.floor(Math.random() * (max - min + 1)) + min~180 مللي ثانية
مع OR البتّي (حيلة)(Math.random() * (max - min +

المدونات

توصيات الكتب