فئة `Number` في جافاسكريبت
تشرح هذه المقالة فئة Number في جافاسكريبت۔
سنشرح بعناية خصائص Number، والمزالق الشائعة، وواجهات برمجة التطبيقات المفيدة، وأمثلة عملية خطوة بخطوة۔
YouTube Video
فئة Number في جافاسكريبت
Number هو النوع الرقمي الأساسي في جافاسكريبت ويتم تمثيله كنقطة عائمة مزدوجة الدقة وفق معيار IEEE-754 (64 بت)۔
الأساسيات: تمثيل الأرقام وفحص النوع
في جافاسكريبت، يتم تمثيل جميع الأرقام بنوع البدائي number۔
1// Primitive numbers and Number object
2const a = 42; // primitive number
3const b = 3.14; // primitive float
4const c = Number(10); // primitive via constructor call (function form)
5const d = new Number(10); // Number object (wrapper)
6
7console.log(typeof a); // "number"
8console.log(typeof d); // "object"
9console.log(c == d); // true (value coerces)
10console.log(c === d); // false (different types)
- يوضح هذا الكود الفرق بين النوع البدائي
numberوكائن التغليفNumber۔ عادةً يتم استخدام الأنواع البدائية بدلاً من كائنات التغليف۔
القيم الخاصة: NaN، Infinity، والثوابت
Number يوفر قيماً خاصة (NaN، Infinity) وثوابت۔
1// Special numeric values and constants
2console.log(Number.NaN); // NaN
3console.log(Number.POSITIVE_INFINITY); // Infinity
4console.log(Number.NEGATIVE_INFINITY); // -Infinity
5
6console.log(Number.MAX_VALUE); // largest positive representable
7console.log(Number.MIN_VALUE); // smallest positive representable (closest to 0)
8console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
9console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
10console.log(Number.EPSILON); // smallest difference ~2.220446049250313e-16
- قد لا يتم تمثيل الأعداد الصحيحة الأكبر من أو تساوي
MAX_SAFE_INTEGERبدقة. يُفضل استخدامBigIntإذا كانت هناك حاجة للدقة۔EPSILONتُستخدم عند المقارنة بين أعداد الفاصلة العائمة۔
تحويل الأرقام: Number() ، parseInt ، parseFloat ، وعامل الجمع +
هناك عدة طرق لتحويل سلسلة نصية إلى رقم، ولكل منها سلوك مختلف۔
1// Converting strings to numbers
2console.log(Number("42")); // 42
3console.log(Number(" 3.14 ")); // 3.14
4console.log(+ "7"); // 7 (unary +)
5
6console.log(parseInt("42px")); // 42
7console.log(parseFloat("3.14abc"));// 3.14
8
9// Careful with parseInt and radix
10console.log(parseInt("08")); // 8
11console.log(parseInt("08", 10)); // 8 (explicit radix is safer)
Number()يعيدNaNإلا إذا كانت السلسلة بالكامل بصيغة رقمية صارمة، في حين أنparseIntوparseFloatتحلل الجزء الرقمي القابل للقراءة في بداية السلسلة۔ من الأكثر أماناً تحديد الأساس (radix) بشكل صريح عند استخدامparseInt۔
التعامل مع التحقق من NaN: الدالتان isNaN و Number.isNaN
NaN (ليس رقم) هي حالة خاصة حيث NaN !== NaN۔ هناك اختلافات في طريقة التحقق؛ الدالة العالمية isNaN تقوم بتحويل النوع وقد تعطي نتائج إيجابية خاطئة، لذلك يُوصى باستخدام Number.isNaN۔
1// NaN detection differences
2console.log(NaN === NaN); // false
3
4console.log(isNaN("foo")); // true -> because "foo" coerces to NaN
5console.log(Number.isNaN("foo")); // false -> "foo" is not the numeric NaN
6
7console.log(Number.isNaN(NaN)); // true
- استخدم
Number.isNaNللتحقق من الأرقام وصحة نتائج العمليات الحسابية لتجنب تحويلات النوع غير الضرورية۔
أخطاء الفاصلة العائمة والمقارنات باستخدام Number.EPSILON
بسبب معيار IEEE-754، تحدث أخطاء مثل 0.1 + 0.2 !== 0.3۔ للمقارنات الصارمة، من الشائع استخدام الفارق و Number.EPSILON۔
1// Floating point precision example and EPSILON comparison
2const sum = 0.1 + 0.2;
3console.log(sum === 0.3); // false
4
5function nearlyEqual(a, b, epsilon = Number.EPSILON) {
6 return Math.abs(a - b) <= epsilon * Math.max(1, Math.abs(a), Math.abs(b));
7}
8
9console.log(nearlyEqual(sum, 0.3)); // true
- عند السماح بوجود أخطاء في المقارنة، يُوصى باستخدام تنفيذ قوي مثل
nearlyEqualالذي يسمح بمقياس وكذلك الفروق المطلقة۔
التحقق من الأعداد الصحيحة والآمنة (isInteger، isSafeInteger)
هناك واجهات برمجة تطبيقات للتحقق مما إذا كانت القيمة عدداً صحيحاً وإذا كانت ضمن النطاق الآمن للأعداد الصحيحة۔
1// Integer and safe integer checks
2console.log(Number.isInteger(3)); // true
3console.log(Number.isInteger(3.0)); // true
4console.log(Number.isInteger(3.1)); // false
5
6console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
7console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
- عند الحاجة لدقة الأعداد الصحيحة الكبيرة، استخدم
Number.isSafeIntegerللتحقق، وفكّر في استخدامBigIntللأعداد التي تتجاوز هذا النطاق۔
العرض والتنسيق: toFixed، toPrecision، toString
هناك طرق متوفرة للتحكم في عرض الأرقام۔ toFixed تعيد سلسلة نصية بعدد منازل عشرية محدد، ولكن يجب الانتباه للتقريب۔
1// Formatting numbers for display
2const x = 1.23456;
3console.log(x.toFixed(2)); // "1.23" (string)
4console.log(x.toPrecision(3)); // "1.23" (string with total significant digits)
5console.log((255).toString(16)); // "ff" (hexadecimal string)
toFixedتعيد قيمة نصية، لذا يجب الانتباه عند تحويلها إلى أرقام لإجراء العمليات الحسابية۔
الاحتياطات بخصوص ربط السلاسل النصية وعامل الجمع +
يُستخدم عامل الجمع + لكل من الجمع الرقمي وربط السلاسل النصية، لذا قد تحدث نتائج غير متوقعة حسب أنواع البيانات المستخدمة۔
1// Pitfall with + operator and type coercion
2console.log(1 + 2 + "px"); // "3px"
3console.log("px" + 1 + 2); // "px12"
4console.log(1 + "2" - 0); // 3 (string coerced to number for subtraction)
- عند الخلط بين السلاسل النصية والأرقام، من الآمن دائماً استخدام
String()أوNumber()أو القوالب النصية لتجنب التحويل الضمني لأنواع البيانات۔
حالات الاستخدام المتقدمة: Number.parseInt / Number.parseFloat ، وvalueOf
Number.parseInt وNumber.parseFloat هما اسمان آخران للدوال العالمية۔ valueOf يُستخدم لاستخراج القيمة البدائية من كائن Number، لكن نادراً ما تحتاج لاستخدامه فعلياً۔
1// Number.parseInt/parseFloat aliases and valueOf example
2console.log(Number.parseInt("100", 10)); // 100
3console.log(Number.parseFloat("3.14")); // 3.14
4
5const nObj = new Number(5);
6console.log(nObj.valueOf()); // 5
7console.log(nObj + 1); // 6 (object coerced to primitive)
- عند استخدام
Number.parseIntوNumber.parseFloat، يجب الانتباه إلى الأساس (radix) وتقليم المدخلات۔ عادةً ما يتم تجنب كائنات التغليف۔
مرجع: مثال صغير - دوال التحقق من الأرقام
فيما يلي بعض الدوال البرمجية الصغيرة التي تجمع الفحوصات الشائعة الاستخدام۔ هذا يجعل مهام مثل التحقق من صحة المدخلات أسهل۔
1// Small number utility functions
2function toNumberStrict(value) {
3 // Return a Number or throw for invalid numeric strings
4 const n = Number(value);
5 if (typeof value === "string" && value.trim() === "") {
6 throw new Error("Empty string is not a valid number");
7 }
8 if (Number.isNaN(n)) {
9 throw new Error(`Invalid number: ${value}`);
10 }
11 return n;
12}
13
14function almostEqual(a, b, eps = Number.EPSILON) {
15 // Robust relative comparison
16 return Math.abs(a - b) <= eps * Math.max(1, Math.abs(a), Math.abs(b));
17}- هذه دوال متعددة الاستخدام ويمكن تكرار استخدامها في معالجة المدخلات والمقارنات۔ التنفيذات التي ترمي أخطاء مفيدة لأغراض التحقق من الصحة۔
ملخص الأداء وأفضل الممارسات
فيما يلي نقاط عملية عند استخدام Number۔
- بشكل أساسي، استخدم النوع البدائي
numberوتجنب استعمالnew Number()۔ - اختر بين
Number()(تحويل صارم) أوparseInt/parseFloat(استخلاص جزئي) عند التحويل من النص إلى الرقم حسب حالتك۔ - استخدم
Number.isNaNوNumber.isFiniteللفحص الآمن۔ - للمقارنات بين الأعداد العشرية، استخدم
Number.EPSILONأو أنشئ دالة مقارنة مخصصة۔ - عندما تتطلب الدقة في الأعداد الصحيحة، استعمل
Number.isSafeInteger، وإذا تجاوزت النطاق المسموح، استخدمBigInt۔ - يمكنك استخدام
toFixedأوtoPrecisionلتقريب الأرقام لغرض العرض، ولكن انتبه أن القيمة المرجعة هي سلسلة نصية۔
الملخص
Number هو النوع الأساسي لجميع الأرقام في جافاسكريبت، بما في ذلك الأعداد الصحيحة والعشرية والقيم الخاصة (NaN وInfinity)۔ من المهم الانتباه لتحويل الأنواع وأخطاء الفاصلة العائمة، واستخدام طرق مثل Number.isNaN و Number.EPSILON بشكل صحيح۔ إذا تم تجاوز النطاق الآمن للأعداد الصحيحة، استخدم BigInt، واستعن بـ toFixed أو toPrecision لعملية التقريب والعرض۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔