الدليل الأساسي لنوع بيانات JavaScript الأحدث: BigInt
نشرت: 2022-03-10Number
أن يمثل بأمان قيمًا أكبر من 2 53 . أجبر هذا القيد المطورين على استخدام الحلول غير الفعالة ومكتبات الجهات الخارجية. BigInt
هو نوع بيانات جديد يهدف إلى إصلاح ذلك. يهدف نوع بيانات BigInt
إلى تمكين مبرمجي JavaScript من تمثيل قيم عدد صحيح أكبر من النطاق الذي يدعمه نوع البيانات Number
. تعتبر القدرة على تمثيل الأعداد الصحيحة بدقة عشوائية مهمة بشكل خاص عند إجراء عمليات حسابية على أعداد صحيحة كبيرة. مع BigInt
، لن يكون تجاوز العدد الصحيح مشكلة.
بالإضافة إلى ذلك ، يمكنك العمل بأمان باستخدام طوابع زمنية عالية الدقة ومعرفات أعداد صحيحة كبيرة والمزيد دون الحاجة إلى استخدام حل بديل. BigInt
هو حاليًا اقتراح من المرحلة 3. بمجرد إضافته إلى المواصفات ، سيصبح نوع البيانات الرقمية الثاني في JavaScript ، مما سيجعل العدد الإجمالي لأنواع البيانات المدعومة ثمانية:
- قيمة منطقية
- باطل
- غير معرف
- رقم
- BigInt
- سلسلة
- رمز
- موضوع
في هذه المقالة ، سوف نلقي نظرة فاحصة على BigInt
ونرى كيف يمكن أن تساعد في التغلب على قيود نوع Number
في JavaScript.
المشكلة
غالبًا ما يكون الافتقار إلى نوع عدد صحيح واضح في JavaScript محيرًا للمبرمجين القادمين من لغات أخرى. تدعم العديد من لغات البرمجة أنواعًا رقمية متعددة مثل float ، و double ، و number number ، و bignum ، ولكن هذا ليس هو الحال مع JavaScript. في JavaScript ، يتم تمثيل جميع الأرقام بتنسيق فاصلة عائمة 64 بت مزدوج الدقة كما هو محدد بواسطة معيار IEEE 754-2008.
وفقًا لهذا المعيار ، يتم تقريب الأعداد الصحيحة الكبيرة جدًا التي لا يمكن تمثيلها بدقة. على وجه الدقة ، يمكن أن يمثل نوع Number
في JavaScript فقط بأمان الأعداد الصحيحة بين -9007199254740991 (- (2 53 -1)) و 9007199254740991 (2 53 -1). قد تفقد أي قيمة عدد صحيح يقع خارج هذا النطاق الدقة.
يمكن فحص ذلك بسهولة عن طريق تنفيذ الكود التالي:
console.log(9999999999999999); // → 10000000000000000
هذا العدد الصحيح أكبر من أكبر عدد يمكن أن يمثله JavaScript بشكل موثوق باستخدام Number
البدائي. لذلك ، يتم تقريبها. يمكن أن يؤدي التقريب غير المتوقع إلى تعريض موثوقية البرنامج وأمانه للخطر. إليك مثال آخر:
// notice the last digits 9007199254740992 === 9007199254740993; // → true
توفر JavaScript ثابت Number.MAX_SAFE_INTEGER
الذي يسمح لك بالحصول بسرعة على أقصى عدد صحيح آمن في JavaScript. وبالمثل ، يمكنك الحصول على الحد الأدنى من عدد صحيح آمن باستخدام Number.MIN_SAFE_INTEGER
ثابت:
const minInt = Number.MIN_SAFE_INTEGER; console.log(minInt); // → -9007199254740991 console.log(minInt - 5); // → -9007199254740996 // notice how this outputs the same value as above console.log(minInt - 4); // → -9007199254740996
الحل
كحل بديل لهذه القيود ، يمثل بعض مطوري JavaScript أعدادًا صحيحة كبيرة باستخدام نوع String
. تضيف Twitter API ، على سبيل المثال ، إصدار سلسلة من المعرفات للكائنات عند الاستجابة باستخدام JSON. بالإضافة إلى ذلك ، تم تطوير عدد من المكتبات مثل bignumber.js لتسهيل العمل مع أعداد صحيحة كبيرة.
باستخدام BigInt
، لم تعد التطبيقات بحاجة إلى حل بديل أو مكتبة لتمثيل أعداد صحيحة بأمان تتجاوز Number.MAX_SAFE_INTEGER
و Number.Min_SAFE_INTEGER
. يمكن الآن إجراء العمليات الحسابية على أعداد صحيحة كبيرة في JavaScript قياسي دون المخاطرة بفقدان الدقة. الميزة الإضافية لاستخدام نوع بيانات أصلي على مكتبة تابعة لجهة خارجية هي أداء وقت تشغيل أفضل.
لإنشاء BigInt
، قم ببساطة بإلحاق n
بنهاية عدد صحيح. قارن:
console.log(9007199254740995n); // → 9007199254740995n console.log(9007199254740995); // → 9007199254740996
بدلاً من ذلك ، يمكنك استدعاء مُنشئ BigInt()
:
BigInt("9007199254740995"); // → 9007199254740995n
يمكن أيضًا كتابة BigInt
literals بتدوين ثنائي أو ثماني أو سداسي عشري:
// binary console.log(0b100000000000000000000000000000000000000000000000000011n); // → 9007199254740995n // hex console.log(0x20000000000003n); // → 9007199254740995n // octal console.log(0o400000000000000003n); // → 9007199254740995n // note that legacy octal syntax is not supported console.log(0400000000000000003n); // → SyntaxError
ضع في اعتبارك أنه لا يمكنك استخدام عامل تشغيل المساواة الصارمة لمقارنة BigInt
برقم عادي لأنهما ليسا من نفس النوع:
console.log(10n === 10); // → false console.log(typeof 10n); // → bigint console.log(typeof 10); // → number
بدلاً من ذلك ، يمكنك استخدام عامل المساواة ، الذي يقوم بإجراء تحويل ضمني للنوع قبل إجراء معاملاته:
console.log(10n == 10); // → true
يمكن استخدام جميع المعاملات الحسابية على BigInt
s باستثناء عامل الجمع الأحادي ( +
):
10n + 20n; // → 30n 10n - 20n; // → -10n +10n; // → TypeError: Cannot convert a BigInt value to a number -10n; // → -10n 10n * 20n; // → 200n 20n / 10n; // → 2n 23n % 10n; // → 3n 10n ** 3n; // → 1000n let x = 10n; ++x; // → 11n --x; // → 10n
السبب في عدم دعم عامل التشغيل أحادي زائد ( +
) هو أن بعض البرامج قد تعتمد على الثابت الذي ينتج عنه +
دائمًا Number
، أو يطرح استثناءً. سيؤدي تغيير سلوك +
أيضًا إلى كسر كود asm.js.

بطبيعة الحال ، عند استخدامها مع معاملات BigInt
، من المتوقع أن تُرجع العوامل الحسابية قيمة BigInt
. لذلك ، يتم اقتطاع نتيجة عامل القسمة ( /
) تلقائيًا. علي سبيل المثال:
25 / 10; // → 2.5 25n / 10n; // → 2n
نوع التحويل الضمني
نظرًا لأن تحويل النوع الضمني قد يفقد المعلومات ، لا يُسمح بالعمليات المختلطة بين BigInt
s و Number
s. عند مزج الأعداد الصحيحة الكبيرة وأرقام الفاصلة العائمة ، قد لا يتم تمثيل القيمة الناتجة بدقة بواسطة BigInt
أو Number
. ضع في اعتبارك المثال التالي:
(9007199254740992n + 1n) + 0.5
تكون نتيجة هذا التعبير خارج مجال كل من BigInt
و Number
. لا يمكن تحويل Number
بجزء كسري بدقة إلى BigInt
. ولا يمكن تحويل BigInt
الأكبر من 2 53 إلى Number
بدقة.
نتيجة لهذا التقييد ، لا يمكن إجراء عمليات حسابية بمزيج من معاملات Number
و BigInt
. لا يمكنك أيضًا تمرير BigInt
إلى واجهات برمجة تطبيقات الويب ووظائف JavaScript المضمنة التي تتوقع Number
. ستؤدي محاولة القيام بذلك إلى حدوث خطأ في TypeError
:
10 + 10n; // → TypeError Math.max(2n, 4n, 6n); // → TypeError
لاحظ أن العوامل الارتباطية لا تتبع هذه القاعدة ، كما هو موضح في هذا المثال:
10n > 5; // → true
إذا كنت تريد إجراء عمليات حسابية باستخدام BigInt
و Number
، فأنت بحاجة أولاً إلى تحديد المجال الذي يجب إجراء العملية فيه. للقيام بذلك ، قم ببساطة بتحويل أي من المعاملين عن طريق استدعاء Number()
أو BigInt()
:
BigInt(10) + 10n; // → 20n // or 10 + Number(10n); // → 20
عند مواجهتها في سياق Boolean
، يتم التعامل مع BigInt
بطريقة مماثلة لـ Number
. بعبارة أخرى ، تعتبر BigInt
قيمة صادقة طالما أنها ليست 0n
:
if (5n) { // this code block will be executed } if (0n) { // but this code block won't }
لا يحدث تحويل نوع ضمني بين أنواع BigInt
و Number
عند فرز مصفوفة:
const arr = [3n, 4, 2, 1n, 0, -1n]; arr.sort(); // → [-1n, 0, 1n, 2, 3n, 4]
عوامل Bitwise مثل |
&
<<
و >>
و ^
على BigInt
s بطريقة مشابهة لـ Number
s. يتم تفسير الأعداد السالبة على أنها تكملة لا نهائية لاثنين. المعاملات المختلطة غير مسموح بها. وهنا بعض الأمثلة:
90 | 115; // → 123 90n | 115n; // → 123n 90n | 115; // → TypeError
منشئ BigInt
كما هو الحال مع الأنواع الأولية الأخرى ، يمكن إنشاء BigInt
باستخدام دالة مُنشئ. يتم تحويل الوسيطة التي تم تمريرها إلى BigInt()
تلقائيًا إلى BigInt
، إذا أمكن:
BigInt("10"); // → 10n BigInt(10); // → 10n BigInt(true); // → 1n
أنواع البيانات والقيم التي لا يمكن تحويلها بطرح استثناء:
BigInt(10.2); // → RangeError BigInt(null); // → TypeError BigInt("abc"); // → SyntaxError
يمكنك إجراء عمليات حسابية مباشرة على BigInt
تم إنشاؤه باستخدام المُنشئ:
BigInt(10) * 10n; // → 100n
عند استخدامها كمعامِلات لمشغل المساواة الصارمة ، يتم التعامل مع BigInt
التي تم إنشاؤها باستخدام مُنشئ على غرار المعاملات العادية:
BigInt(true) === 1n; // → true
وظائف المكتبة
يوفر JavaScript وظيفتين للمكتبة لتمثيل قيم BigInt
صحيحة موقعة أو بدون إشارة:
-
BigInt.asUintN(width, BigInt)
BigInt
التفاف كبير بين 0 و 2 عرض -1 -
BigInt.asIntN(width, BigInt)
BigInt
التفاف كبير بين -2 عرض -1 و 2 عرض -1 -1
هذه الوظائف مفيدة بشكل خاص عند إجراء عمليات حسابية 64 بت. بهذه الطريقة يمكنك البقاء ضمن النطاق المقصود.
دعم المتصفح و Transpiling
في وقت كتابة هذه السطور ، كان Chrome +67 و Opera +54 يدعمان تمامًا نوع بيانات BigInt
. لسوء الحظ ، فإن Edge و Safari لم ينفذهما بعد. لا يدعم Firefox BigInt
افتراضيًا ، ولكن يمكن تمكينه عن طريق تعيين javascript.options.bigint
على true
في about:config
. قائمة محدثة من المتصفحات المدعومة متاحة على Can I use….
لسوء الحظ ، يعد تحويل BigInt
عملية معقدة للغاية ، والتي تؤدي إلى عقوبة أداء كبيرة في وقت التشغيل. من المستحيل أيضًا تعويض BigInt
بشكل مباشر لأن الاقتراح يغير سلوك العديد من المشغلين الحاليين. في الوقت الحالي ، هناك بديل أفضل وهو استخدام مكتبة JSBI ، وهي عبارة عن تطبيق JavaScript خالص لاقتراح BigInt
.
توفر هذه المكتبة واجهة برمجة تطبيقات تتصرف تمامًا مثل BigInt
الأصلي. إليك كيفية استخدام JSBI:
import JSBI from './jsbi.mjs'; const b1 = JSBI.BigInt(Number.MAX_SAFE_INTEGER); const b2 = JSBI.BigInt('10'); const result = JSBI.add(b1, b2); console.log(String(result)); // → '9007199254741001'
تتمثل إحدى ميزات استخدام JSBI في أنه بمجرد تحسين دعم المتصفح ، فلن تحتاج إلى إعادة كتابة التعليمات البرمجية الخاصة بك. بدلاً من ذلك ، يمكنك ترجمة كود JSBI تلقائيًا إلى رمز BigInt
الأصلي باستخدام مكون Babel الإضافي. علاوة على ذلك ، يتساوى أداء JSBI مع تطبيقات BigInt
الأصلية. يمكنك توقع دعم متصفح أوسع لـ BigInt
قريبًا.
خاتمة
BigInt
هو نوع بيانات جديد مخصص للاستخدام عندما تكون قيم الأعداد الصحيحة أكبر من النطاق الذي يدعمه نوع البيانات Number
. يتيح لنا نوع البيانات هذا إجراء عمليات حسابية بأمان على أعداد صحيحة كبيرة ، وتمثيل طوابع زمنية عالية الدقة ، واستخدام معرفات أعداد صحيحة كبيرة ، والمزيد دون الحاجة إلى استخدام مكتبة.
من المهم أن تضع في اعتبارك أنه لا يمكنك إجراء عمليات حسابية بمزيج من معاملات Number
و BigInt
. ستحتاج إلى تحديد المجال الذي يجب إجراء العملية فيه عن طريق التحويل الصريح لأي من المعاملين. علاوة على ذلك ، لأسباب تتعلق بالتوافق ، لا يُسمح لك باستخدام عامل التشغيل أحادي زائد ( +
) على BigInt
.
ما رأيك؟ هل تجد BigInt
مفيدًا؟ اسمحوا لنا أن نعرف في التعليقات!