كيفية تنسيق الأرقام إلى منزلتين عشريتين في JavaScript
عرض الأرقام بمنزلتين عشريتين بالضبط للأسعار والنسب المئوية والقياسات
مقدمة
تحتاج العديد من التطبيقات إلى عرض الأرقام بعدد ثابت من المنازل العشرية. عادةً ما تُظهر الأسعار منزلتين عشريتين مثل $19.99. غالبًا ما تُعرض النسب المئوية كـ 45.50%. تستخدم القياسات منازل عشرية متسقة لسهولة القراءة مثل 3.14 متر.
يضمن التحكم في المنازل العشرية الاتساق البصري عبر تطبيقك. بدون تنسيق صريح، تعرض JavaScript الأرقام بمنازل عشرية متفاوتة بناءً على قيمتها الفعلية. يُعرض الرقم 5 كـ "5" بينما يُعرض 5.5 كـ "5.5"، مما يخلق محاذاة ومظهرًا غير متسقين.
يوضح هذا الدرس كيفية تنسيق الأرقام إلى منزلتين عشريتين بالضبط، أو حتى منزلتين عشريتين، بطريقة تحترم اصطلاحات اللغات المختلفة.
استخدام toFixed() للتنسيق الأساسي
تحول الدالة toFixed() رقمًا إلى سلسلة نصية بعدد محدد من المنازل العشرية. مرر عدد المنازل العشرية كمعامل.
const price = 19.9;
const formatted = price.toFixed(2);
console.log(formatted);
// Output: "19.90"
تعرض الدالة دائمًا منزلتين عشريتين بالضبط. إذا كان الرقم يحتوي على منازل عشرية أقل، تضيف toFixed() أصفارًا. وإذا كان يحتوي على منازل عشرية أكثر، تقوم الدالة بالتقريب إلى منزلتين.
const examples = [5, 5.5, 5.555, 5.999];
examples.forEach(num => {
console.log(num.toFixed(2));
});
// Output:
// "5.00"
// "5.50"
// "5.56"
// "6.00"
تُرجع الدالة toFixed() سلسلة نصية، وليس رقمًا. هذا مقصود لأن الأصفار اللاحقة لها معنى للعرض ولكن ستُفقد إذا أُرجعت كرقم.
مشكلة اللغة مع toFixed()
تستخدم الدالة toFixed() دائمًا النقطة كفاصل عشري، بغض النظر عن لغة المستخدم. تستخدم العديد من البلدان الفاصلة كفاصل عشري بدلاً من النقطة.
const price = 19.99;
console.log(price.toFixed(2));
// Output: "19.99" (always uses period)
بالنسبة للمستخدمين في ألمانيا وفرنسا وإسبانيا والعديد من البلدان الأخرى، يبدو هذا خاطئاً. إنهم يتوقعون رؤية "19,99" بدلاً من "19.99". لا يمكن لطريقة toFixed() إنتاج مخرجات مناسبة للغة المحلية.
لتنسيق الأرقام بشكل صحيح للغات المحلية المختلفة، استخدم واجهة برمجة التطبيقات Intl.NumberFormat.
استخدام Intl.NumberFormat للتنسيق الواعي باللغة المحلية
تقوم واجهة برمجة التطبيقات Intl.NumberFormat بتنسيق الأرقام وفقاً لاصطلاحات اللغة المحلية. أنشئ منسقاً باستخدام لغة محلية وخيارات، ثم استدعِ طريقة format() الخاصة به مع رقم.
const formatter = new Intl.NumberFormat("de-DE", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
const price = 19.99;
console.log(formatter.format(price));
// Output: "19,99" (uses comma for German locale)
ينتج نفس المنسق مخرجات مختلفة للغات محلية مختلفة.
const price = 19.99;
const usFormatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
const deFormatter = new Intl.NumberFormat("de-DE", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(usFormatter.format(price));
// Output: "19.99"
console.log(deFormatter.format(price));
// Output: "19,99"
يتغير الفاصل العشري تلقائياً بناءً على اللغة المحلية.
التنسيق بمنزلتين عشريتين بالضبط
لعرض منزلتين عشريتين بالضبط، اضبط كلاً من minimumFractionDigits و maximumFractionDigits على 2. يضمن هذا أن يحتوي المخرج دائماً على منزلتين عشريتين، مع إضافة أصفار عند الحاجة والتقريب عندما يكون للرقم دقة أكبر.
const formatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.format(5));
// Output: "5.00"
console.log(formatter.format(5.5));
// Output: "5.50"
console.log(formatter.format(5.555));
// Output: "5.56"
يتحكم خيار minimumFractionDigits في الأصفار اللاحقة. بدونه، لن تظهر الأرقام ذات المنازل العشرية الأقل الأصفار.
const withoutMinimum = new Intl.NumberFormat("en-US", {
maximumFractionDigits: 2
});
console.log(withoutMinimum.format(5));
// Output: "5"
const withMinimum = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(withMinimum.format(5));
// Output: "5.00"
يضمن تعيين كلا الخيارين لنفس القيمة منازل عشرية متسقة عبر جميع الأرقام.
التنسيق بما يصل إلى منزلتين عشريتين
في بعض الأحيان تريد إظهار المنازل العشرية فقط عند الحاجة، بحد أقصى منزلتين. اضبط maximumFractionDigits على 2 و minimumFractionDigits على 0 أو احذفه تماماً.
const formatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 0,
maximumFractionDigits: 2
});
console.log(formatter.format(5));
// Output: "5"
console.log(formatter.format(5.5));
// Output: "5.5"
console.log(formatter.format(5.555));
// Output: "5.56"
يزيل هذا النهج الأصفار اللاحقة ولكنه لا يزال يحد من الدقة إلى منزلتين عشريتين. إنه يعمل بشكل جيد لعرض القياسات أو الإحصائيات حيث لا تضيف الأصفار اللاحقة أي معلومات.
القيمة الافتراضية لـ minimumFractionDigits هي 0 لتنسيق الأرقام العادية، لذا يمكنك حذفها.
const formatter = new Intl.NumberFormat("en-US", {
maximumFractionDigits: 2
});
console.log(formatter.format(5));
// Output: "5"
console.log(formatter.format(5.5));
// Output: "5.5"
إعادة استخدام أدوات التنسيق لأداء أفضل
إنشاء نسخة جديدة من Intl.NumberFormat مكلف نسبياً. إذا كنت تقوم بتنسيق العديد من الأرقام بنفس الخيارات، قم بإنشاء أداة التنسيق مرة واحدة وأعد استخدامها.
const formatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
const prices = [19.99, 29.5, 99, 149.999];
prices.forEach(price => {
console.log(formatter.format(price));
});
// Output:
// "19.99"
// "29.50"
// "99.00"
// "150.00"
هذا النمط أكثر كفاءة من إنشاء أداة تنسيق جديدة لكل رقم.
متى تستخدم كل نهج
استخدم منزلتين عشريتين بالضبط عند عرض الأسعار أو المبالغ النقدية أو أي قيمة تكون فيها المنازل العشرية ذات معنى دلالي. عرض "$5.00" بدلاً من "$5" يشير إلى الدقة ويتوافق مع توقعات المستخدم للأسعار.
استخدم ما يصل إلى منزلتين عشريتين عند عرض الإحصائيات أو القياسات أو القيم المحسوبة حيث لا تضيف الأصفار اللاحقة أي معلومات. عرض "5 أمتار" بدلاً من "5.00 متر" أكثر وضوحاً وسهولة في القراءة.
استخدم toFixed() فقط عندما تكون متأكداً من أن جميع المستخدمين يستخدمون نفس اصطلاح الفاصل العشري، أو عندما لا يكون الناتج موجهاً للمستخدم. بالنسبة للتطبيقات المعولمة، يُفضل استخدام Intl.NumberFormat.
استخدام اللغة المفضلة للمستخدم
بدلاً من تحديد لغة ثابتة، استخدم تفضيلات لغة متصفح المستخدم. توفر خاصية navigator.language اللغة المفضلة للمستخدم.
const formatter = new Intl.NumberFormat(navigator.language, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
const price = 19.99;
console.log(formatter.format(price));
// Output varies by user's locale
// For en-US: "19.99"
// For de-DE: "19,99"
// For fr-FR: "19,99"
يمكنك أيضاً تمرير مصفوفة navigator.languages بالكامل للسماح لواجهة برمجة التطبيقات Intl باختيار أول لغة مدعومة من تفضيلات المستخدم.
const formatter = new Intl.NumberFormat(navigator.languages, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
يوفر هذا النهج احتياطياً تلقائياً إذا لم يكن التفضيل الأول للمستخدم مدعوماً.